@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
@@ -48,17 +48,11 @@ export interface AbTestResult {
48
48
 
49
49
  const AB_TEST_KEYS = {
50
50
  BP_3926_FREEMIUM_WATERMARK: 'bc-bp-3926-freemium-cta-in-website-editor',
51
- BP_4572_AI_TEXT_GENERATION_POST_PURCHASE:
52
- 'bc-bp-4572-ai-text-generation-post-purchase',
53
- BP_4964_AI_TEXT_GENERATION_IMPROVEMENT:
54
- 'bc-bp-4964-ai-text-improvement-post-purchase-on-website',
55
- BP_5245_AI_WEBSITE_ASSISTANT: 'bc-bp-5245-ai-website-assistant',
51
+ BP_5245_AI_WEBSITE_ASSISTANT: 'bc-bp-5245-ai-website-assistant-postpurchase',
56
52
  };
57
53
 
58
54
  export interface AbTest {
59
55
  bp_3926_freemium_watermark?: AbTestResult;
60
- bp_4572_ai_text_generation_post_purchase?: AbTestResult;
61
- bp_4964_ai_text_generation_improvement?: AbTestResult;
62
56
  bp_5245_ai_website_assistant?: AbTestResult;
63
57
  }
64
58
 
@@ -133,24 +127,6 @@ export const getAbTestResults = (abtestKeyValues: AbTest): AbTest => {
133
127
  );
134
128
  }
135
129
 
136
- // AB Test for BP-4572 - AI Text Generation Post Purchase
137
-
138
- if (abtestKeyValues[AB_TEST_KEYS.BP_4572_AI_TEXT_GENERATION_POST_PURCHASE]) {
139
- abTests.bp_4572_ai_text_generation_post_purchase = getValueType(
140
- AB_TEST_KEYS.BP_4572_AI_TEXT_GENERATION_POST_PURCHASE,
141
- abtestKeyValues[AB_TEST_KEYS.BP_4572_AI_TEXT_GENERATION_POST_PURCHASE],
142
- );
143
- }
144
-
145
- // AB Test for BP-4572 - AI Text Generation Improvement
146
-
147
- if (abtestKeyValues[AB_TEST_KEYS.BP_4964_AI_TEXT_GENERATION_IMPROVEMENT]) {
148
- abTests.bp_4964_ai_text_generation_improvement = getValueType(
149
- AB_TEST_KEYS.BP_4964_AI_TEXT_GENERATION_IMPROVEMENT,
150
- abtestKeyValues[AB_TEST_KEYS.BP_4964_AI_TEXT_GENERATION_IMPROVEMENT],
151
- );
152
- }
153
-
154
130
  // AB Test for BP-5245 - AI Website Assistant
155
131
 
156
132
  if (abtestKeyValues[AB_TEST_KEYS.BP_5245_AI_WEBSITE_ASSISTANT]) {
@@ -211,6 +211,7 @@ export type TiktokContent = ButtonContent;
211
211
 
212
212
  export const ASPECT_RATIOS = {
213
213
  Default: '',
214
+ original: '',
214
215
  '1:1': '1/1',
215
216
  '16:9': '16/9',
216
217
  '9:16': '9/16',
@@ -45,3 +45,51 @@ describe('color.util - getNewColorBasedOnTargetColorTheme', () => {
45
45
  });
46
46
  });
47
47
  });
48
+
49
+ describe('color.util - getNewColorBasedOnTargetColorTheme near-grayscale snap', () => {
50
+ // Reproducer for LangSmith trace 4e116ea3 (the "orangy drum"). The trio's
51
+ // secondary was #fffcfa — perceptually white but HSL(24°, 100%, 99%). Without
52
+ // the snap, multi-fill SVGs got their dark layers recolored to a saturated
53
+ // burnt-orange tint of that residual hue.
54
+ test('off-white target on a dark fill snaps to neutral grey (no orange tint)', () => {
55
+ // #231f20 grayscale lightness ≈ 12.5%. With the snap, the result is a
56
+ // near-black neutral grey, not a saturated rust.
57
+ const newColor = getNewColorBasedOnTargetColorTheme('#231f20', '#fffcfa');
58
+ const [r, g, b] = newColor!.rgb().array();
59
+
60
+ expect(Math.abs(r - g)).toBeLessThan(2);
61
+ expect(Math.abs(g - b)).toBeLessThan(2);
62
+ expect(r).toBeLessThan(40); // near-black, not bright orange
63
+ });
64
+
65
+ test('near-black target on a light fill snaps to neutral grey (no green tint)', () => {
66
+ // #020503 is HSL(140°, ~51%, 1.5%) — practically black, but with hue. A
67
+ // light original fill would otherwise become a saturated green.
68
+ const newColor = getNewColorBasedOnTargetColorTheme('#d4d4d4', '#020503');
69
+ const [r, g, b] = newColor!.rgb().array();
70
+
71
+ expect(Math.abs(r - g)).toBeLessThan(2);
72
+ expect(Math.abs(g - b)).toBeLessThan(2);
73
+ expect(r).toBeGreaterThan(200); // stays light grey
74
+ });
75
+
76
+ test('genuine pastel target still produces hue-shifted output', () => {
77
+ // #ffcc99 (peach) has chroma 102/255 ≈ 40% — well above the threshold. The
78
+ // hue should still come through (red channel dominates).
79
+ const newColor = getNewColorBasedOnTargetColorTheme('#333333', '#ffcc99');
80
+ const [r, g, b] = newColor!.rgb().array();
81
+
82
+ expect(r).toBeGreaterThan(b);
83
+ expect(r).toBeGreaterThan(g);
84
+ });
85
+
86
+ test('genuine cool navy target still produces hue-shifted output', () => {
87
+ // The trace's primary #0c1824 has chroma 24/255 ≈ 9.4% — above the
88
+ // threshold. When used as a target it should still imprint its cool hue
89
+ // onto the recoloured fills.
90
+ const newColor = getNewColorBasedOnTargetColorTheme('#cccccc', '#0c1824');
91
+ const [r, , b] = newColor!.rgb().array();
92
+
93
+ expect(b).toBeGreaterThan(r); // blue channel dominates, hue preserved
94
+ });
95
+ });
@@ -97,16 +97,41 @@ export const getThemeByTextStyleAndLogoTheme = (
97
97
  };
98
98
  };
99
99
 
100
+ // RGB chroma threshold (0..1) below which a colour is treated as perceptually
101
+ // grayscale even when its HSL saturation is non-zero. Off-whites like #fffcfa
102
+ // report 100% HSL saturation but have ~2% chroma; applying that hue+saturation
103
+ // on top of a dark original fill in `getNewColorBasedOnTargetColorTheme`
104
+ // produces a saturated tint of the residual hue (e.g. #fffcfa → burnt-orange
105
+ // at low lightness) rather than the perceived "white".
106
+ const NEAR_GRAYSCALE_CHROMA_THRESHOLD = 0.05;
107
+
108
+ const isNearGrayscale = (color: ColorInstance): boolean => {
109
+ const [r, g, b] = color.rgb().array();
110
+
111
+ return (
112
+ (Math.max(r, g, b) - Math.min(r, g, b)) / 255 <
113
+ NEAR_GRAYSCALE_CHROMA_THRESHOLD
114
+ );
115
+ };
116
+
100
117
  export const getNewColorBasedOnTargetColorTheme = (
101
118
  originalColor: string,
102
119
  targetColor: string,
103
120
  ): ColorInstance | undefined => {
104
121
  try {
105
122
  const originalColorGrayScaled = Color(originalColor).grayscale().hsl();
106
-
107
- const targetHslColor = Color(targetColor)
108
- .hsl()
109
- .lightness(originalColorGrayScaled.lightness());
123
+ const targetColorObj = Color(targetColor);
124
+
125
+ // Snap saturation to 0 when the target is perceptually grayscale. Without
126
+ // this, multi-fill SVG recolour (callers in `shape-color-utils.ts`)
127
+ // injects the target's residual hue into the original's lightness layer,
128
+ // producing visible hue where the user "meant" white/black.
129
+ const targetHslColor = isNearGrayscale(targetColorObj)
130
+ ? targetColorObj
131
+ .hsl()
132
+ .saturationl(0)
133
+ .lightness(originalColorGrayScaled.lightness())
134
+ : targetColorObj.hsl().lightness(originalColorGrayScaled.lightness());
110
135
 
111
136
  return targetHslColor.rgb();
112
137
  } catch (e) {
@@ -6,14 +6,23 @@ declare global {
6
6
  }
7
7
  }
8
8
 
9
+ interface RaygunOptions {
10
+ tags?: string[];
11
+ customData?: Record<string, unknown>;
12
+ }
13
+
9
14
  export default {
10
- safeSendRaygunError: (err: Error) => {
15
+ safeSendRaygunError: (err: Error, options?: RaygunOptions) => {
11
16
  if (typeof window?.Raygun?.send !== 'function') {
12
17
  return;
13
18
  }
14
19
 
15
20
  try {
16
- window.Raygun.send(err);
21
+ if (options) {
22
+ window.Raygun.send(err, options.customData, options.tags);
23
+ } else {
24
+ window.Raygun.send(err);
25
+ }
17
26
  } catch (e) {
18
27
  console.error(e);
19
28
  }
@@ -157,13 +157,11 @@ export const applyColorReplacementsToSvgString = (
157
157
  ): string => {
158
158
  const scopeId = `id-${uuid.v4()}`;
159
159
 
160
- const newSvg = modifySvgMetadata({
160
+ return modifySvgMetadata({
161
161
  svgString: svgString,
162
162
  replacementColors: colorReplacements,
163
163
  scopeId: scopeId,
164
164
  });
165
-
166
- return newSvg;
167
165
  };
168
166
 
169
167
  export const applyColorToSvgString = (
@@ -1237,10 +1237,7 @@ export const mapToPageFooterViewModel = (
1237
1237
  copyrightText: pageFooter.copyrightText,
1238
1238
  copyrightStyle,
1239
1239
  displayStyle: pageFooter.displayStyle,
1240
- iconStyle: Object.assign(
1241
- { fill: pageStyles.textStyles?.style.color },
1242
- pageFooter.iconStyle,
1243
- ),
1240
+ iconStyle: { ...pageFooter.iconStyle },
1244
1241
  logo: mapToLogoViewModel(logoContent, logoStyles, useOldLogoRenderSize),
1245
1242
  socialLinks: pageFooter.socialLinks,
1246
1243
  textFontFamily: pageFooter.textFontFamily,
@@ -26,10 +26,10 @@
26
26
  v-model="inputText"
27
27
  :placeholder="placeholder"
28
28
  rows="3"
29
- class="chatbox-textarea tw-font-sans tw-box-border tw-w-full tw-py-3 tw-pr-14 tw-text-base lg:tw-text-sm tw-px-4 tw-rounded-xl tw-border tw-border-solid tw-border-grayscale-200 tw-bg-grayscale-100 tw-transition-all tw-duration-300 tw-ease-out tw-resize-none tw-overflow-y-auto tw-outline-none"
29
+ class="chatbox-textarea tw-font-sans tw-box-border tw-w-full tw-py-3 tw-pr-14 lg:tw-pr-16 tw-text-base lg:tw-text-sm tw-px-4 tw-rounded-xl tw-border tw-border-solid tw-border-grayscale-200 tw-bg-grayscale-100 tw-transition-all tw-duration-300 tw-ease-out tw-resize-none tw-overflow-y-auto tw-outline-none"
30
30
  @keydown.enter.exact.prevent="onSend"
31
31
  />
32
- <div class="tw-absolute tw-bottom-2 tw-right-2 tw-mb-2">
32
+ <div class="tw-absolute tw-bottom-2 tw-right-2 md:tw-right-5 tw-mb-2">
33
33
  <Button
34
34
  icon="arrow-up"
35
35
  icon-size="sm"
@@ -0,0 +1,162 @@
1
+ <template>
2
+ <div data-component="ai-progress-feed">
3
+ <!-- Phase 1: Personalized acknowledgment -->
4
+ <p v-if="initialMessage" class="shimmer-text tw-text-sm tw-mb-2">
5
+ {{ initialMessage }}
6
+ </p>
7
+ <!-- Phase 1.5: Planning indicator (while planner runs, before plan_announced) -->
8
+ <div
9
+ v-if="initialMessage && !planItems.length && isTyping"
10
+ class="tw-flex tw-items-center tw-gap-2 tw-text-sm tw-animate-fade-in tw-mt-2"
11
+ >
12
+ <span class="step-spinner tw-flex-shrink-0" />
13
+ <span class="tw-text-grayscale-700">Working out the details...</span>
14
+ </div>
15
+ <!-- Phase 2: Dynamic checklist -->
16
+ <div v-if="planItems.length" class="tw-flex tw-flex-col tw-gap-3">
17
+ <div
18
+ v-for="item in sortedPlanItems"
19
+ :key="item.id"
20
+ class="tw-flex tw-items-center tw-gap-2 tw-text-sm tw-animate-fade-in"
21
+ >
22
+ <!-- Complete -->
23
+ <template v-if="isItemComplete(item)">
24
+ <svg
25
+ class="tw-text-success-500 tw-flex-shrink-0"
26
+ width="16"
27
+ height="16"
28
+ viewBox="0 0 16 16"
29
+ fill="none"
30
+ >
31
+ <path
32
+ d="M3 8.5L6.5 12L13 5"
33
+ stroke="currentColor"
34
+ stroke-width="2.2"
35
+ stroke-linecap="round"
36
+ stroke-linejoin="round"
37
+ />
38
+ </svg>
39
+ <span class="tw-text-grayscale-600">{{ item.completeLabel }}</span>
40
+ </template>
41
+
42
+ <!-- Active (first incomplete item) -->
43
+ <template v-else-if="item.id === firstIncompleteId">
44
+ <span class="step-spinner tw-flex-shrink-0" />
45
+ <span class="tw-text-grayscale-700">
46
+ {{ item.pendingLabel }}
47
+ <span v-if="item.subIds?.length" class="tw-text-grayscale-500">
48
+ ({{ completedSubCount(item) }}/{{ item.subIds.length }})
49
+ </span>
50
+ </span>
51
+ </template>
52
+
53
+ <!-- Pending (not yet started) -->
54
+ <template v-else>
55
+ <span class="tw-text-grayscale-500 tw-flex-shrink-0">&#9675;</span>
56
+ <span class="tw-text-grayscale-600">{{ item.pendingLabel }}</span>
57
+ </template>
58
+ </div>
59
+ <div
60
+ v-if="allItemsComplete && isTyping"
61
+ class="tw-flex tw-items-center tw-gap-2 tw-text-sm tw-animate-fade-in"
62
+ >
63
+ <span class="step-spinner tw-flex-shrink-0" />
64
+ <span class="tw-text-grayscale-700">Consolidating your website...</span>
65
+ </div>
66
+ </div>
67
+ </div>
68
+ </template>
69
+
70
+ <script setup lang="ts">
71
+ import { computed } from 'vue';
72
+ import { type PlanItem } from '../../../clients/websocket-gateway-client';
73
+
74
+ interface Props {
75
+ planItems: PlanItem[];
76
+ completedItemIds: string[];
77
+ initialMessage?: string;
78
+ isTyping: boolean;
79
+ }
80
+
81
+ const props = defineProps<Props>();
82
+
83
+ const isItemComplete = (item: PlanItem) =>
84
+ item.subIds?.length
85
+ ? item.subIds.every((id) => props.completedItemIds.includes(id))
86
+ : props.completedItemIds.includes(item.id);
87
+
88
+ const completedSubCount = (item: PlanItem) =>
89
+ item.subIds?.filter((id) => props.completedItemIds.includes(id)).length ?? 0;
90
+
91
+ const allItemsComplete = computed(
92
+ () => props.planItems.length > 0 && props.planItems.every(isItemComplete),
93
+ );
94
+
95
+ const sortedPlanItems = computed(() => {
96
+ const completed = props.planItems.filter(isItemComplete);
97
+ const pending = props.planItems.filter((item) => !isItemComplete(item));
98
+ return [...completed, ...pending];
99
+ });
100
+
101
+ const firstIncompleteId = computed(
102
+ () => props.planItems.find((item) => !isItemComplete(item))?.id ?? null,
103
+ );
104
+ </script>
105
+
106
+ <style scoped>
107
+ .shimmer-text {
108
+ background: linear-gradient(
109
+ 90deg,
110
+ #9ca3af 0%,
111
+ #9ca3af 35%,
112
+ #e5e7eb 50%,
113
+ #9ca3af 65%,
114
+ #9ca3af 100%
115
+ );
116
+ background-size: 250% 100%;
117
+ -webkit-background-clip: text;
118
+ -webkit-text-fill-color: transparent;
119
+ background-clip: text;
120
+ animation: shimmer-slide 4s linear infinite;
121
+ }
122
+
123
+ @keyframes shimmer-slide {
124
+ from {
125
+ background-position: 200% center;
126
+ }
127
+ to {
128
+ background-position: -200% center;
129
+ }
130
+ }
131
+
132
+ .step-spinner {
133
+ display: inline-block;
134
+ width: 14px;
135
+ height: 14px;
136
+ border-radius: 50%;
137
+ border: 2px solid transparent;
138
+ border-top-color: #798bf9;
139
+ animation: spin 0.7s linear infinite;
140
+ }
141
+
142
+ @keyframes spin {
143
+ to {
144
+ transform: rotate(360deg);
145
+ }
146
+ }
147
+
148
+ .tw-animate-fade-in {
149
+ animation: fade-in 0.3s ease-in;
150
+ }
151
+
152
+ @keyframes fade-in {
153
+ from {
154
+ opacity: 0;
155
+ transform: translateY(4px);
156
+ }
157
+ to {
158
+ opacity: 1;
159
+ transform: translateY(0);
160
+ }
161
+ }
162
+ </style>
@@ -2,20 +2,27 @@
2
2
  <div class="tw-mb-4" :class="containerClass">
3
3
  <div class="tw-flex" :class="containerClass">
4
4
  <div
5
- class="tw-p-4 tw-px-2 tw-rounded-lg tw-flex tw-items-start tw-max-w-md"
5
+ class="tw-p-5 tw-rounded-lg tw-flex tw-items-start tw-max-w-md"
6
6
  :class="bubbleClass"
7
7
  >
8
8
  <SparkleIcon
9
- v-if="isAi || isTyping"
9
+ v-if="isAi && !isTyping"
10
10
  color-class="tw-text-primary-500"
11
- :animated="isTyping"
11
+ :animated="false"
12
12
  class="tw-mr-2 tw-flex tw-flex-shrink-0 tw-mt-0.5"
13
13
  />
14
14
  <div class="tw-flex-1">
15
15
  <div class="tw-text-sm tw-whitespace-pre-wrap" :class="textClass">
16
16
  <slot>
17
17
  <span v-if="!isTyping || displayedText" v-html="displayedText" />
18
- <span v-else class="tw-text-grayscale-600 tw-italic">
18
+ <AiProgressFeed
19
+ v-else-if="initialMessage || planItems.length"
20
+ :plan-items="planItems"
21
+ :completed-item-ids="completedItemIds"
22
+ :initial-message="initialMessage"
23
+ :is-typing="isTyping"
24
+ />
25
+ <span v-else class="shimmer-text">
19
26
  {{ generateAiModalTr('thinkingResponse') }}
20
27
  </span>
21
28
  </slot>
@@ -49,7 +56,9 @@
49
56
  import { computed, ref, watch } from 'vue';
50
57
  import { SparkleIcon } from '@designcrowd/fe-shared-lib';
51
58
  import AiActionButtons from './AiActionButtons.vue';
59
+ import AiProgressFeed from './AiProgressFeed.vue';
52
60
  import { generateAiModalTr } from '../../../composables/useTranslate';
61
+ import { type PlanItem } from '../../../clients/websocket-gateway-client';
53
62
 
54
63
  interface Props {
55
64
  text?: string;
@@ -63,6 +72,9 @@ interface Props {
63
72
  disableAnimation?: boolean; // Flag to disable typing animation (for restored messages)
64
73
  isDesignCom?: boolean;
65
74
  langChainUrl?: string;
75
+ initialMessage?: string;
76
+ planItems?: PlanItem[];
77
+ completedItemIds?: string[];
66
78
  }
67
79
 
68
80
  const props = withDefaults(defineProps<Props>(), {
@@ -77,6 +89,9 @@ const props = withDefaults(defineProps<Props>(), {
77
89
  disableAnimation: false,
78
90
  isDesignCom: false,
79
91
  langChainUrl: undefined,
92
+ initialMessage: undefined,
93
+ planItems: () => [],
94
+ completedItemIds: () => [],
80
95
  });
81
96
 
82
97
  defineEmits<{
@@ -86,6 +101,7 @@ defineEmits<{
86
101
  }>();
87
102
 
88
103
  const copiedFeedback = ref(false);
104
+ let copiedResetTimeout: ReturnType<typeof setTimeout> | null = null;
89
105
 
90
106
  const langChainUrlLabel = computed(() =>
91
107
  copiedFeedback.value ? 'Copied!' : 'Thread URL',
@@ -94,10 +110,21 @@ const langChainUrlLabel = computed(() =>
94
110
  const copyLangChainUrl = async () => {
95
111
  if (!props.langChainUrl) return;
96
112
 
113
+ if (copiedFeedback.value) {
114
+ if (copiedResetTimeout) {
115
+ clearTimeout(copiedResetTimeout);
116
+ copiedResetTimeout = null;
117
+ }
118
+ copiedFeedback.value = false;
119
+ window.open(props.langChainUrl, '_blank', 'noopener,noreferrer');
120
+ return;
121
+ }
122
+
97
123
  await navigator.clipboard.writeText(props.langChainUrl);
98
124
  copiedFeedback.value = true;
99
- setTimeout(() => {
125
+ copiedResetTimeout = setTimeout(() => {
100
126
  copiedFeedback.value = false;
127
+ copiedResetTimeout = null;
101
128
  }, 2000);
102
129
  };
103
130
 
@@ -219,4 +246,29 @@ const showActions = computed(() => {
219
246
  opacity: 0;
220
247
  }
221
248
  }
249
+
250
+ .shimmer-text {
251
+ background: linear-gradient(
252
+ 90deg,
253
+ #9ca3af 0%,
254
+ #9ca3af 35%,
255
+ #e5e7eb 50%,
256
+ #9ca3af 65%,
257
+ #9ca3af 100%
258
+ );
259
+ background-size: 250% 100%;
260
+ -webkit-background-clip: text;
261
+ -webkit-text-fill-color: transparent;
262
+ background-clip: text;
263
+ animation: shimmer-slide 4s linear infinite;
264
+ }
265
+
266
+ @keyframes shimmer-slide {
267
+ from {
268
+ background-position: 200% center;
269
+ }
270
+ to {
271
+ background-position: -200% center;
272
+ }
273
+ }
222
274
  </style>
@@ -1,25 +1,5 @@
1
1
  {
2
2
  "aiModal": {
3
- "generateTitle": "Text mit KI generieren",
4
- "generateDescription": "Der Inhalt wurde von einer KI generiert und muss möglicherweise zur Verbesserung der Genauigkeit bearbeitet werden",
5
- "generatePlaceholder": "Beschreiben Sie Ihren Text.",
6
- "generationStopped": "Die Textgenerierung wurde gestoppt. Starten Sie eine neue Eingabeaufforderung, um fortzufahren.",
7
- "generateInputPlaceholder": "Geben Sie Ihre Eingabeaufforderung ein, um den Text zu beschreiben ...",
8
- "stopGeneration": "Generierung anhalten",
9
- "useText": "Text verwenden",
10
- "promptTooLong": "Der Prompt darf maximal {{maxLength}} Zeichen lang sein ({{currentLength}})",
11
- "generateText": "Erstellen Sie {{ location }}",
12
- "improveText": "Meinen Text verbessern",
13
- "spellCheck": "Rechtschreibprüfung",
14
- "generateTextPrompt": "Schreiben Sie ein einprägsames {{fieldName}} für {{businessName}}, ein {{industry}} Unternehmen. Gestalten Sie es freundlich und einladend.",
15
- "generateTextPromptWithIndustry": "Ein einprägsames {{fieldName}} schreiben für ein Unternehmen in der folgenden Branche: {{industry}}. Freundlich und einladend gestalten.",
16
- "generateTextPromptWithBusinessName": "Ein einprägsames {{fieldName}} schreiben für {{businessName}}. Freundlich und einladend gestalten.",
17
- "generateTextPromptSimple": "Ein einprägsames {{fieldName}} schreiben. Freundlich und einladend gestalten.",
18
- "improveTextPrompt": "Diesen Text für {{businessName}} verbessern, ein Unternehmen in der folgenden Branche: {{industry}}. Natürlicher, klarer und professioneller formulieren.",
19
- "improveTextPromptWithIndustry": "Diesen Text für {{industry}} verbessern. Natürlicher, klarer und professioneller formulieren.",
20
- "improveTextPromptWithBusinessName": "Diesen Text für {{businessName}} verbessern. Natürlicher, klarer und professioneller formulieren.",
21
- "improveTextPromptSimple": "Diesen Text verbessern. Natürlicher, klarer und professioneller formulieren.",
22
- "spellCheckPrompt": "Prüfen Sie diesen Text auf Rechtschreibung und Grammatik.",
23
3
  "stop": "Stopp",
24
4
  "thinkingResponse": "Ich überlege mir eine Antwort …"
25
5
  }
@@ -1,25 +1,5 @@
1
1
  {
2
2
  "aiModal": {
3
- "generateTitle": "Generar texto con IA",
4
- "generateDescription": "El contenido se genera mediante IA y podría necesitar una revisión para garantizar su precisión",
5
- "generatePlaceholder": "Describe tu texto.",
6
- "generationStopped": "El proceso de generación se ha detenido. Envía un nuevo mensaje para continuar.",
7
- "generateInputPlaceholder": "Introduce tu mensaje para describir el texto...",
8
- "stopGeneration": "Detén la generación",
9
- "useText": "Usa texto",
10
- "promptTooLong": "El mensaje debe tener {{maxLength}} caracteres como máximo ({{currentLength}})",
11
- "generateText": "Genera {{ location }}",
12
- "improveText": "Mejora mi texto",
13
- "spellCheck": "Comprueba la ortografía",
14
- "generateTextPrompt": "Escribe un {{fieldName}} pegadizo para {{businessName}}, un negocio {{industry}}. Hazlo amigable y acogedor.",
15
- "generateTextPromptWithIndustry": "Escribe una {{fieldName}} que llame la atención para un negocio en el sector de {{industry}}. Haz que resulte cordial y agradable.",
16
- "generateTextPromptWithBusinessName": "Escribe una {{fieldName}} que llame la atención para {{businessName}}. Haz que resulte cordial y agradable.",
17
- "generateTextPromptSimple": "Escribe una {{fieldName}} que llame la atención. Haz que resulte cordial y agradable.",
18
- "improveTextPrompt": "Mejora este texto para {{businessName}}, un negocio de {{industry}}. Haz que suene más natural, claro y profesional.",
19
- "improveTextPromptWithIndustry": "Mejora este texto para un negocio de {{industry}}. Haz que suene más natural, claro y profesional.",
20
- "improveTextPromptWithBusinessName": "Mejora este texto para {{businessName}}. Haz que suene más natural, claro y profesional.",
21
- "improveTextPromptSimple": "Mejora este texto. Haz que suene más natural, claro y profesional.",
22
- "spellCheckPrompt": "Verificar la ortografía y la gramática de este texto.",
23
3
  "stop": "Detener",
24
4
  "thinkingResponse": "Pensando una respuesta..."
25
5
  }
@@ -1,25 +1,5 @@
1
1
  {
2
2
  "aiModal": {
3
- "generateTitle": "Générer du texte avec l'IA",
4
- "generateDescription": "Le contenu est généré par l'IA et peut nécessiter des modifications pour plus de précision.",
5
- "generatePlaceholder": "Décrivez votre texte.",
6
- "generationStopped": "La génération de texte s'est arrêtée. Lancez une nouvelle requête pour continuer.",
7
- "generateInputPlaceholder": "Entrez votre requête pour décrire le contenu...",
8
- "stopGeneration": "Arrêter la génération",
9
- "useText": "Utiliser le texte",
10
- "promptTooLong": "La requête doit comporter {{maxLength}} caractères ou moins ({{currentLength}})",
11
- "generateText": "Générer {{ location }}",
12
- "improveText": "Améliorez votre texte",
13
- "spellCheck": "Vérification orthographique",
14
- "generateTextPrompt": "Rédigez un(e) {{fieldName}} accrocheur(-se) pour {{businessName}}, une entreprise de {{industry}}. Votre création devrait être chaleureuse et accueillante.",
15
- "generateTextPromptWithIndustry": "Rédigez un(e) {{fieldName}} pour une entreprise de ce secteur : {{industry}}. Votre création devrait être chaleureuse et accueillante.",
16
- "generateTextPromptWithBusinessName": "Rédigez un(e) {{fieldName}} accrocheur(-se) pour {{businessName}}. Votre création devrait être chaleureuse et accueillante.",
17
- "generateTextPromptSimple": "Rédigez un(e) {{fieldName}} accrocheur(-se). Votre création devrait être chaleureuse et accueillante.",
18
- "improveTextPrompt": "Améliorez ce texte pour {{businessName}}, une entreprise de {{industry}}. Rendez-le plus naturel, clair et professionnel.",
19
- "improveTextPromptWithIndustry": "Améliorez ce texte pour une entreprise de {{industry}}. Rendez-le plus naturel, clair et professionnel.",
20
- "improveTextPromptWithBusinessName": "Améliorez ce texte pour {{businessName}}. Rendez-le plus naturel, clair et professionnel.",
21
- "improveTextPromptSimple": "Améliorez ce texte. Rendez-le plus naturel, clair et professionnel.",
22
- "spellCheckPrompt": "Vérifiez l'orthographe et la grammaire de ce texte.",
23
3
  "stop": "Arrêtez",
24
4
  "thinkingResponse": "Je réfléchis à une réponse…"
25
5
  }
@@ -1,25 +1,5 @@
1
1
  {
2
2
  "aiModal": {
3
- "generateTitle": "Générer du texte avec l'IA",
4
- "generateDescription": "Le contenu est généré par l'IA et peut nécessiter des modifications pour plus de précision.",
5
- "generatePlaceholder": "Décrivez votre texte.",
6
- "generationStopped": "La génération de texte s'est arrêtée. Démarrez une nouvelle invite pour continuer.",
7
- "generateInputPlaceholder": "Entrez votre prompt pour décrire le contenu...",
8
- "stopGeneration": "Arrêter la génération",
9
- "useText": "Utiliser le texte",
10
- "promptTooLong": "L'invite doit comporter {{maxLength}} caractères ou moins ({{currentLength}})",
11
- "generateText": "Générer {{ location }}",
12
- "improveText": "Améliorez mon texte",
13
- "spellCheck": "Vérification orthographique",
14
- "generateTextPrompt": "Rédigez un {{fieldName}} accrocheur pour {{businessName}}, une entreprise de {{industry}}. Rendez-le chaleureux et accueillant.",
15
- "generateTextPromptWithIndustry": "Rédigez un {{fieldName}} accrocheur pour une entreprise de ce secteur : {{industry}}. Rendez-le chaleureux et accueillant.",
16
- "generateTextPromptWithBusinessName": "Rédigez un {{fieldName}} accrocheur pour {{businessName}}. Rendez-le chaleureux et accueillant.",
17
- "generateTextPromptSimple": "Rédigez un {{fieldName}} accrocheur. Rendez-le chaleureux et accueillant.",
18
- "improveTextPrompt": "Améliorez ce texte pour {{businessName}}, une entreprise de {{industry}}. Donnez-lui un ton plus naturel, plus clair et plus professionnel.",
19
- "improveTextPromptWithIndustry": "Améliorez ce texte pour une entreprise de {{industry}}. Donnez-lui un ton plus naturel, plus clair et plus professionnel.",
20
- "improveTextPromptWithBusinessName": "Améliorez ce texte pour {{businessName}}. Donnez-lui un ton plus naturel, plus clair et plus professionnel.",
21
- "improveTextPromptSimple": "Améliorez ce texte. Donnez-lui un ton plus naturel, plus clair et plus professionnel.",
22
- "spellCheckPrompt": "Vérifiez l'orthographe et la grammaire de ce texte.",
23
3
  "stop": "Arrêtez",
24
4
  "thinkingResponse": "Je réfléchis à une réponse…"
25
5
  }
@@ -1,25 +1,5 @@
1
1
  {
2
2
  "aiModal": {
3
- "generateTitle": "Generate Text with AI",
4
- "generateDescription": "Content is AI-generated and may require editing for accuracy",
5
- "generatePlaceholder": "Describe your text.",
6
- "generationStopped": "Text generation stopped. Start a new prompt to continue.",
7
- "generateInputPlaceholder": "Enter your prompt to describe the text...",
8
- "stopGeneration": "Stop generation",
9
- "useText": "Use text",
10
- "promptTooLong": "Prompt must be {{maxLength}} characters or less ({{currentLength}})",
11
- "generateText": "Generate {{ location }}",
12
- "improveText": "Improve my text",
13
- "spellCheck": "Spell Check",
14
- "generateTextPrompt": "Write a catchy {{fieldName}} for {{businessName}}, a {{industry}} business. Make it friendly and inviting.",
15
- "generateTextPromptWithIndustry": "Write a catchy {{fieldName}} for a business in the {{industry}} industry. Make it friendly and inviting.",
16
- "generateTextPromptWithBusinessName": "Write a catchy {{fieldName}} for {{businessName}}. Make it friendly and inviting.",
17
- "generateTextPromptSimple": "Write a catchy {{fieldName}}. Make it friendly and inviting.",
18
- "improveTextPrompt": "Improve this text for {{businessName}}, a {{industry}} business. Make it sound more natural, clear, and professional.",
19
- "improveTextPromptWithIndustry": "Improve this text for a {{industry}} business. Make it sound more natural, clear, and professional.",
20
- "improveTextPromptWithBusinessName": "Improve this text for {{businessName}}. Make it sound more natural, clear, and professional.",
21
- "improveTextPromptSimple": "Improve this text. Make it sound more natural, clear, and professional.",
22
- "spellCheckPrompt": "Check this text for spelling and grammar.",
23
3
  "stop": "Stop",
24
4
  "thinkingResponse": "Thinking of a response..."
25
5
  }