@dev.smartpricing/message-composer-layer 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. package/README.md +75 -0
  2. package/app/api/ai.ts +28 -0
  3. package/app/api/brands.ts +54 -0
  4. package/app/api/client.ts +56 -0
  5. package/app/api/compilation.ts +34 -0
  6. package/app/api/dynamicValues.ts +11 -0
  7. package/app/api/index.ts +11 -0
  8. package/app/api/languages.ts +6 -0
  9. package/app/api/media.ts +26 -0
  10. package/app/api/messageGroups.ts +49 -0
  11. package/app/api/messages.ts +22 -0
  12. package/app/api/meta.ts +18 -0
  13. package/app/api/tracking.ts +9 -0
  14. package/app/components/Brand/BrandDrawer.vue +281 -0
  15. package/app/components/Brand/BrandPreview.vue +137 -0
  16. package/app/components/Brand/Steps/BrandStepGeneral.vue +37 -0
  17. package/app/components/Brand/Steps/BrandStepSocials.vue +48 -0
  18. package/app/components/Brand/Steps/BrandStepVisual.vue +214 -0
  19. package/app/components/Common/BrandColorSwatches.vue +37 -0
  20. package/app/components/Common/ColorInput.vue +144 -0
  21. package/app/components/Common/EmojiPickerButton.vue +35 -0
  22. package/app/components/Common/FontFamilySelect.vue +39 -0
  23. package/app/components/Common/HtmlPreviewIframe.vue +68 -0
  24. package/app/components/Common/IncompleteTranslationsDialog.vue +97 -0
  25. package/app/components/Common/LanguageList.vue +356 -0
  26. package/app/components/Common/LoadingOverlay.vue +12 -0
  27. package/app/components/Common/MediaUploadOrSelect.vue +299 -0
  28. package/app/components/Common/MessagePreviewSlideover.vue +88 -0
  29. package/app/components/Common/MonacoEditor.vue +110 -0
  30. package/app/components/Common/PhoneInput.vue +804 -0
  31. package/app/components/Common/SectionHeader.vue +26 -0
  32. package/app/components/Common/TranslationActionBar.vue +139 -0
  33. package/app/components/Common/ViewLessMore.vue +40 -0
  34. package/app/components/CreateTemplateButton.vue +59 -0
  35. package/app/components/DynamicDataButton.vue +75 -0
  36. package/app/components/DynamicDataSlideover.vue +149 -0
  37. package/app/components/Editor/AiGenerateSlideover.vue +292 -0
  38. package/app/components/Editor/EditorLinkPopover.vue +154 -0
  39. package/app/components/Editor/RichTextEditor.vue +495 -0
  40. package/app/components/Email/Editor/BlockLibrary.vue +89 -0
  41. package/app/components/Email/Editor/BlockSettings.vue +60 -0
  42. package/app/components/Email/Editor/Blocks/ButtonBlock.vue +117 -0
  43. package/app/components/Email/Editor/Blocks/ButtonSettings.vue +228 -0
  44. package/app/components/Email/Editor/Blocks/DiscountCodeBlock.vue +74 -0
  45. package/app/components/Email/Editor/Blocks/DiscountCodeSettings.vue +162 -0
  46. package/app/components/Email/Editor/Blocks/DividerBlock.vue +31 -0
  47. package/app/components/Email/Editor/Blocks/DividerSettings.vue +108 -0
  48. package/app/components/Email/Editor/Blocks/FooterBlock.vue +61 -0
  49. package/app/components/Email/Editor/Blocks/FooterSettings.vue +123 -0
  50. package/app/components/Email/Editor/Blocks/GridBlock.vue +128 -0
  51. package/app/components/Email/Editor/Blocks/GridSettings.vue +109 -0
  52. package/app/components/Email/Editor/Blocks/HTMLBlock.vue +31 -0
  53. package/app/components/Email/Editor/Blocks/HTMLSettings.vue +85 -0
  54. package/app/components/Email/Editor/Blocks/HeaderBlock.vue +53 -0
  55. package/app/components/Email/Editor/Blocks/HeaderSettings.vue +113 -0
  56. package/app/components/Email/Editor/Blocks/HeadingBlock.vue +61 -0
  57. package/app/components/Email/Editor/Blocks/HeadingSettings.vue +156 -0
  58. package/app/components/Email/Editor/Blocks/ImageBlock.vue +49 -0
  59. package/app/components/Email/Editor/Blocks/ImageSettings.vue +53 -0
  60. package/app/components/Email/Editor/Blocks/IndexBlock.vue +155 -0
  61. package/app/components/Email/Editor/Blocks/ParagraphBlock.vue +61 -0
  62. package/app/components/Email/Editor/Blocks/ParagraphSettings.vue +157 -0
  63. package/app/components/Email/Editor/Blocks/SocialsBlock.vue +63 -0
  64. package/app/components/Email/Editor/Blocks/SocialsSettings.vue +117 -0
  65. package/app/components/Email/Editor/Blocks/SpacerBlock.vue +37 -0
  66. package/app/components/Email/Editor/Blocks/SpacerSettings.vue +95 -0
  67. package/app/components/Email/Editor/Blocks/TopProductsBlock.vue +47 -0
  68. package/app/components/Email/Editor/Blocks/TopProductsSettings.vue +87 -0
  69. package/app/components/Email/Editor/Blocks/UnsubscribeLinkBlock.vue +61 -0
  70. package/app/components/Email/Editor/Blocks/UnsubscribeLinkSettings.vue +123 -0
  71. package/app/components/Email/Editor/Canvas.vue +143 -0
  72. package/app/components/Email/Editor/GeneralStyleSettings.vue +125 -0
  73. package/app/components/Email/Editor/Index.vue +77 -0
  74. package/app/components/Email/Editor/LeftSidebar.vue +95 -0
  75. package/app/components/Email/InlinePreview.vue +124 -0
  76. package/app/components/Email/Preview.vue +126 -0
  77. package/app/components/Email/PreviewPanel.vue +57 -0
  78. package/app/components/Email/SendTestEmailModal.vue +121 -0
  79. package/app/components/Email/TranslationEditor.vue +198 -0
  80. package/app/components/Email/Translator/Button.vue +101 -0
  81. package/app/components/Email/Translator/Discount.vue +60 -0
  82. package/app/components/Email/Translator/Footer.vue +66 -0
  83. package/app/components/Email/Translator/Grid.vue +127 -0
  84. package/app/components/Email/Translator/Header.vue +90 -0
  85. package/app/components/Email/Translator/Heading.vue +66 -0
  86. package/app/components/Email/Translator/Image.vue +91 -0
  87. package/app/components/Email/Translator/Index.vue +138 -0
  88. package/app/components/Email/Translator/Paragraph.vue +66 -0
  89. package/app/components/Email/Translator/RawHtml.vue +64 -0
  90. package/app/components/Email/Translator/UnsubscribeLink.vue +59 -0
  91. package/app/components/TemplateList/BaseTable.vue +354 -0
  92. package/app/components/TemplateList/StatusCell.vue +67 -0
  93. package/app/components/Whatsapp/CategoryChanger.vue +63 -0
  94. package/app/components/Whatsapp/Editor/Body.vue +53 -0
  95. package/app/components/Whatsapp/Editor/Buttons.vue +341 -0
  96. package/app/components/Whatsapp/Editor/Footer.vue +70 -0
  97. package/app/components/Whatsapp/Editor/Header.vue +156 -0
  98. package/app/components/Whatsapp/Editor/Index.vue +89 -0
  99. package/app/components/Whatsapp/Editor/SyncWrapper.vue +166 -0
  100. package/app/components/Whatsapp/Preview.vue +197 -0
  101. package/app/components/Whatsapp/PreviewPanel.vue +24 -0
  102. package/app/components/Whatsapp/TranslationEditor.vue +150 -0
  103. package/app/components/Whatsapp/Translator/Body.vue +61 -0
  104. package/app/components/Whatsapp/Translator/Button.vue +209 -0
  105. package/app/components/Whatsapp/Translator/Footer.vue +56 -0
  106. package/app/components/Whatsapp/Translator/Header.vue +61 -0
  107. package/app/components/Whatsapp/Translator/HeaderMedia.vue +117 -0
  108. package/app/components/Whatsapp/Translator/Index.vue +159 -0
  109. package/app/composables/composerContext.ts +35 -0
  110. package/app/composables/useAutoTranslate.ts +242 -0
  111. package/app/composables/useAutoTranslateEmail.ts +294 -0
  112. package/app/composables/useChangeTracking.ts +212 -0
  113. package/app/composables/useChangeTrackingEmail.ts +227 -0
  114. package/app/composables/useChannels.ts +36 -0
  115. package/app/composables/useEmailBlockContext.ts +43 -0
  116. package/app/composables/useExitConfirmation.ts +39 -0
  117. package/app/composables/useGoBack.ts +15 -0
  118. package/app/composables/useIncompleteTranslations.ts +55 -0
  119. package/app/composables/useIncompleteTranslationsEmail.ts +56 -0
  120. package/app/composables/useMediaLimits.ts +42 -0
  121. package/app/composables/useTemplateFormValidation.ts +109 -0
  122. package/app/composables/useTemplateOperations.ts +147 -0
  123. package/app/composables/useTracking.ts +39 -0
  124. package/app/composables/useTranslationFilters.ts +176 -0
  125. package/app/composables/useTranslationFiltersEmail.ts +244 -0
  126. package/app/composables/useWhatsappTemplateBehaviors.ts +58 -0
  127. package/app/middleware/channel-guard.ts +13 -0
  128. package/app/pages/brands.vue +195 -0
  129. package/app/pages/images.vue +141 -0
  130. package/app/pages/index.vue +198 -0
  131. package/app/pages/preview/[id].vue +47 -0
  132. package/app/pages/template/email/[id].vue +596 -0
  133. package/app/pages/template/email/create.vue +562 -0
  134. package/app/pages/template/whatsapp/[id].vue +561 -0
  135. package/app/pages/template/whatsapp/create.vue +468 -0
  136. package/app/plugins/admin-shortcut.client.ts +7 -0
  137. package/app/plugins/tracking.client.ts +12 -0
  138. package/app/queries/ai.ts +20 -0
  139. package/app/queries/brands.ts +75 -0
  140. package/app/queries/compilation.ts +37 -0
  141. package/app/queries/dynamicValues.ts +13 -0
  142. package/app/queries/index.ts +9 -0
  143. package/app/queries/languages.ts +10 -0
  144. package/app/queries/media.ts +27 -0
  145. package/app/queries/messageGroups.ts +112 -0
  146. package/app/queries/messages.ts +42 -0
  147. package/app/queries/meta.ts +13 -0
  148. package/app/stores/adminStore.ts +50 -0
  149. package/app/stores/appContext.ts +99 -0
  150. package/app/stores/emailEditor.ts +220 -0
  151. package/app/stores/main.ts +3 -0
  152. package/app/stores/metaSubmission.ts +116 -0
  153. package/app/types/app-config.d.ts +14 -0
  154. package/app/types/hooks.d.ts +9 -0
  155. package/app/types/tracking.ts +148 -0
  156. package/app/utils/locale.ts +17 -0
  157. package/app/utils/notifyParent.ts +7 -0
  158. package/app/utils/resolveDefaultLanguage.ts +14 -0
  159. package/app/utils/socialDefaults.ts +42 -0
  160. package/app/utils/testIds.const.ts +728 -0
  161. package/app.config.ts +5 -0
  162. package/i18n/check-translations.ts +56 -0
  163. package/i18n/locales/de.ts +834 -0
  164. package/i18n/locales/en.ts +826 -0
  165. package/i18n/locales/es.ts +833 -0
  166. package/i18n/locales/fr.ts +837 -0
  167. package/i18n/locales/it.ts +831 -0
  168. package/nuxt.config.ts +65 -0
  169. package/package.json +64 -0
@@ -0,0 +1,728 @@
1
+ export const homeTestIds = {
2
+ page: 'home-page',
3
+ navbar: 'home-navbar',
4
+ createTemplateButton: 'home-create-template-button',
5
+ createTemplateDropdown: 'home-create-template-dropdown',
6
+ tabs: 'home-tabs',
7
+ templateTable: 'home-template-table',
8
+ } as const
9
+
10
+ export const navigationTestIds = {
11
+ appPage: 'app-page',
12
+ } as const
13
+
14
+ export const imagesPageTestIds = {
15
+ page: 'images-page',
16
+ navbar: 'images-navbar',
17
+ loadingIcon: 'images-loading-icon',
18
+ emptyState: 'images-empty-state',
19
+ grid: 'images-grid',
20
+ card: 'images-card',
21
+ image: 'images-card-image',
22
+ fileName: 'images-card-file-name',
23
+ syncBadge: 'images-card-sync-badge',
24
+ syncButton: 'images-card-sync-button',
25
+ } as const
26
+
27
+ export const templateEmailCreateTestIds = {
28
+ page: 'template-email-create-page',
29
+ navbar: 'template-email-create-navbar',
30
+ cancelButton: 'template-email-create-cancel-button',
31
+ saveDraftButton: 'template-email-create-save-draft-button',
32
+ saveTemplateButton: 'template-email-create-save-template-button',
33
+ tabs: 'template-email-create-tabs',
34
+ validationAlert: 'template-email-create-validation-alert',
35
+ contentCard: 'template-email-create-content-card',
36
+ nameInput: 'template-email-create-name-input',
37
+ subjectInput: 'template-email-create-subject-input',
38
+ internalSwitch: 'template-email-create-internal-switch',
39
+ translationsCard: 'template-email-create-translations-card',
40
+ } as const
41
+
42
+ export const templateEmailEditTestIds = {
43
+ page: 'template-email-edit-page',
44
+ navbar: 'template-email-edit-navbar',
45
+ cancelButton: 'template-email-edit-cancel-button',
46
+ saveDraftButton: 'template-email-edit-save-draft-button',
47
+ saveTemplateButton: 'template-email-edit-save-template-button',
48
+ tabs: 'template-email-edit-tabs',
49
+ validationAlert: 'template-email-edit-validation-alert',
50
+ contentCard: 'template-email-edit-content-card',
51
+ nameInput: 'template-email-edit-name-input',
52
+ subjectInput: 'template-email-edit-subject-input',
53
+ translationsCard: 'template-email-edit-translations-card',
54
+ } as const
55
+
56
+ export const templateWhatsappCreateTestIds = {
57
+ page: 'template-whatsapp-create-page',
58
+ navbar: 'template-whatsapp-create-navbar',
59
+ cancelButton: 'template-whatsapp-create-cancel-button',
60
+ saveDraftButton: 'template-whatsapp-create-save-draft-button',
61
+ requestApprovalButton: 'template-whatsapp-create-request-approval-button',
62
+ tabs: 'template-whatsapp-create-tabs',
63
+ validationAlert: 'template-whatsapp-create-validation-alert',
64
+ contentCard: 'template-whatsapp-create-content-card',
65
+ nameInput: 'template-whatsapp-create-name-input',
66
+ internalSwitch: 'template-whatsapp-create-internal-switch',
67
+ translationsCard: 'template-whatsapp-create-translations-card',
68
+ } as const
69
+
70
+ export const templateWhatsappEditTestIds = {
71
+ page: 'template-whatsapp-edit-page',
72
+ navbar: 'template-whatsapp-edit-navbar',
73
+ cancelButton: 'template-whatsapp-edit-cancel-button',
74
+ saveDraftButton: 'template-whatsapp-edit-save-draft-button',
75
+ saveAsNewButton: 'template-whatsapp-edit-save-as-new-button',
76
+ requestApprovalButton: 'template-whatsapp-edit-request-approval-button',
77
+ tabs: 'template-whatsapp-edit-tabs',
78
+ validationAlert: 'template-whatsapp-edit-validation-alert',
79
+ contentCard: 'template-whatsapp-edit-content-card',
80
+ nameInput: 'template-whatsapp-edit-name-input',
81
+ translationsCard: 'template-whatsapp-edit-translations-card',
82
+ } as const
83
+
84
+ export const previewPageTestIds = {
85
+ page: 'preview-page',
86
+ } as const
87
+
88
+ // ─── Common components ─────────────────────────────────────────────
89
+
90
+ export const colorInputTestIds = {
91
+ popover: 'color-input-popover',
92
+ triggerButton: 'color-input-trigger-button',
93
+ picker: 'color-input-picker',
94
+ hexInput: 'color-input-hex-input',
95
+ } as const
96
+
97
+ export const emojiPickerTestIds = {
98
+ popover: 'emoji-picker-popover',
99
+ triggerButton: 'emoji-picker-trigger-button',
100
+ picker: 'emoji-picker',
101
+ } as const
102
+
103
+ export const fontFamilySelectTestIds = {
104
+ formField: 'font-family-select-form-field',
105
+ select: 'font-family-select',
106
+ } as const
107
+
108
+ export const incompleteTranslationsDialogTestIds = {
109
+ modal: 'incomplete-translations-dialog-modal',
110
+ modalCloseButton: 'incomplete-translations-dialog-close-button',
111
+ description: 'incomplete-translations-dialog-description',
112
+ noteAlert: 'incomplete-translations-dialog-note-alert',
113
+ goToTranslationsButton: 'incomplete-translations-dialog-go-to-translations-button',
114
+ cancelButton: 'incomplete-translations-dialog-cancel-button',
115
+ translateAndSaveButton: 'incomplete-translations-dialog-translate-and-save-button',
116
+ } as const
117
+
118
+ export const languageListTestIds = {
119
+ root: 'language-list',
120
+ addPopover: 'language-list-add-popover',
121
+ addButton: 'language-list-add-button',
122
+ commandPalette: 'language-list-command-palette',
123
+ languageItem: 'language-list-item',
124
+ deleteButton: 'language-list-delete-button',
125
+ } as const
126
+
127
+ export const loadingOverlayTestIds = {
128
+ root: 'loading-overlay',
129
+ } as const
130
+
131
+ export const loadingPageTestIds = {
132
+ root: 'loading-page',
133
+ progress: 'loading-page-progress',
134
+ } as const
135
+
136
+ export const mediaUploadTestIds = {
137
+ root: 'media-upload',
138
+ limitationsAlert: 'media-upload-limitations-alert',
139
+ fileUpload: 'media-upload-file-upload',
140
+ previewImage: 'media-upload-preview-image',
141
+ previewFile: 'media-upload-preview-file',
142
+ modal: 'media-upload-modal',
143
+ modalCloseButton: 'media-upload-modal-close-button',
144
+ selectLibraryButton: 'media-upload-select-library-button',
145
+ searchInput: 'media-upload-search-input',
146
+ emptyState: 'media-upload-empty-state',
147
+ noResultsState: 'media-upload-no-results-state',
148
+ imageGrid: 'media-upload-image-grid',
149
+ imageItem: 'media-upload-image-item',
150
+ fileList: 'media-upload-file-list',
151
+ fileItem: 'media-upload-file-item',
152
+ } as const
153
+
154
+ export const messagePreviewSlideoverTestIds = {
155
+ slideover: 'message-preview-slideover',
156
+ slideoverCloseButton: 'message-preview-slideover-close-button',
157
+ triggerButton: 'message-preview-slideover-trigger-button',
158
+ } as const
159
+
160
+ export const monacoEditorTestIds = {
161
+ container: 'monaco-editor-container',
162
+ } as const
163
+
164
+ export const phoneInputTestIds = {
165
+ formField: 'phone-input-form-field',
166
+ prefixSelect: 'phone-input-prefix-select',
167
+ numberInput: 'phone-input-number-input',
168
+ } as const
169
+
170
+ export const sectionHeaderTestIds = {
171
+ root: 'section-header',
172
+ resetButton: 'section-header-reset-button',
173
+ } as const
174
+
175
+ export const translationActionBarTestIds = {
176
+ root: 'translation-action-bar',
177
+ searchInput: 'translation-action-bar-search-input',
178
+ showMissingSwitch: 'translation-action-bar-show-missing-switch',
179
+ showChangesSwitch: 'translation-action-bar-show-changes-switch',
180
+ autoTranslateButton: 'translation-action-bar-auto-translate-button',
181
+ } as const
182
+
183
+ export const viewLessMoreTestIds = {
184
+ root: 'view-less-more',
185
+ toggleButton: 'view-less-more-toggle-button',
186
+ } as const
187
+
188
+ // ─── Email Editor ─────────────────────────────────────────────────
189
+
190
+ export const emailEditorIndexTestIds = {
191
+ container: 'email-editor-index-container',
192
+ viewTabs: 'email-editor-index-view-tabs',
193
+ } as const
194
+
195
+ export const blockLibraryTestIds = {
196
+ container: 'block-library-container',
197
+ blockItem: 'block-library-block-item',
198
+ } as const
199
+
200
+ export const blockSettingsTestIds = {
201
+ container: 'block-settings-container',
202
+ notAvailable: 'block-settings-not-available',
203
+ } as const
204
+
205
+ export const canvasTestIds = {
206
+ container: 'canvas-container',
207
+ scrollArea: 'canvas-scroll-area',
208
+ pageBackground: 'canvas-page-background',
209
+ contentArea: 'canvas-content-area',
210
+ blockItem: 'canvas-block-item',
211
+ } as const
212
+
213
+ export const generalStyleSettingsTestIds = {
214
+ container: 'general-style-settings-container',
215
+ fontFamilySelect: 'general-style-settings-font-family-select',
216
+ textColorInput: 'general-style-settings-text-color-input',
217
+ backgroundColorInput: 'general-style-settings-background-color-input',
218
+ bodyColorInput: 'general-style-settings-body-color-input',
219
+ verticalSpacingField: 'general-style-settings-vertical-spacing-field',
220
+ verticalSpacingSlider: 'general-style-settings-vertical-spacing-slider',
221
+ horizontalSpacingField: 'general-style-settings-horizontal-spacing-field',
222
+ horizontalSpacingSlider: 'general-style-settings-horizontal-spacing-slider',
223
+ resetButton: 'general-style-settings-reset-button',
224
+ } as const
225
+
226
+ export const leftSidebarTestIds = {
227
+ container: 'left-sidebar-container',
228
+ tabs: 'left-sidebar-tabs',
229
+ backButton: 'left-sidebar-back-button',
230
+ } as const
231
+
232
+ // ─── Email Translator ─────────────────────────────────────────────
233
+
234
+ export const emailTranslatorIndexTestIds = {
235
+ root: 'email-translator-index',
236
+ blockCard: 'email-translator-index-block-card',
237
+ } as const
238
+
239
+ export const emailTranslatorButtonTestIds = {
240
+ root: 'email-translator-button',
241
+ basePreview: 'email-translator-button-base-preview',
242
+ linkTypeBadge: 'email-translator-button-link-type-badge',
243
+ copyUrlButton: 'email-translator-button-copy-url-button',
244
+ contentEditor: 'email-translator-button-content-editor',
245
+ urlInput: 'email-translator-button-url-input',
246
+ } as const
247
+
248
+ export const emailTranslatorDiscountTestIds = {
249
+ root: 'email-translator-discount',
250
+ basePreview: 'email-translator-discount-base-preview',
251
+ contentEditor: 'email-translator-discount-content-editor',
252
+ } as const
253
+
254
+ export const emailTranslatorFooterTestIds = {
255
+ root: 'email-translator-footer',
256
+ basePreview: 'email-translator-footer-base-preview',
257
+ contentEditor: 'email-translator-footer-content-editor',
258
+ } as const
259
+
260
+ export const emailTranslatorGridTestIds = {
261
+ root: 'email-translator-grid',
262
+ nestedBlock: 'email-translator-grid-nested-block',
263
+ nestedBlockBadge: 'email-translator-grid-nested-block-badge',
264
+ emptyState: 'email-translator-grid-empty-state',
265
+ } as const
266
+
267
+ export const emailTranslatorHeaderTestIds = {
268
+ root: 'email-translator-header',
269
+ basePreviewImage: 'email-translator-header-base-preview-image',
270
+ mediaUpload: 'email-translator-header-media-upload',
271
+ resetButton: 'email-translator-header-reset-button',
272
+ altInput: 'email-translator-header-alt-input',
273
+ } as const
274
+
275
+ export const emailTranslatorHeadingTestIds = {
276
+ root: 'email-translator-heading',
277
+ basePreview: 'email-translator-heading-base-preview',
278
+ contentEditor: 'email-translator-heading-content-editor',
279
+ } as const
280
+
281
+ export const emailTranslatorImageTestIds = {
282
+ root: 'email-translator-image',
283
+ basePreviewImage: 'email-translator-image-base-preview-image',
284
+ mediaUpload: 'email-translator-image-media-upload',
285
+ resetButton: 'email-translator-image-reset-button',
286
+ hrefInput: 'email-translator-image-href-input',
287
+ } as const
288
+
289
+ export const emailTranslatorParagraphTestIds = {
290
+ root: 'email-translator-paragraph',
291
+ basePreview: 'email-translator-paragraph-base-preview',
292
+ contentEditor: 'email-translator-paragraph-content-editor',
293
+ } as const
294
+
295
+ export const emailTranslatorRawHtmlTestIds = {
296
+ root: 'email-translator-raw-html',
297
+ basePreview: 'email-translator-raw-html-base-preview',
298
+ monacoEditor: 'email-translator-raw-html-monaco-editor',
299
+ copyFromBaseButton: 'email-translator-raw-html-copy-from-base-button',
300
+ } as const
301
+
302
+ export const emailTranslatorUnsubscribeLinkTestIds = {
303
+ root: 'email-translator-unsubscribe-link',
304
+ basePreview: 'email-translator-unsubscribe-link-base-preview',
305
+ contentEditor: 'email-translator-unsubscribe-link-content-editor',
306
+ } as const
307
+
308
+ // ─── Email root ───────────────────────────────────────────────────
309
+
310
+ export const emailPreviewTestIds = {
311
+ root: 'email-preview',
312
+ loadingSkeleton: 'email-preview-loading-skeleton',
313
+ subject: 'email-preview-subject',
314
+ iframe: 'email-preview-iframe',
315
+ emptyState: 'email-preview-empty-state',
316
+ } as const
317
+
318
+ export const emailPreviewPanelTestIds = {
319
+ root: 'email-preview-panel',
320
+ viewTabs: 'email-preview-panel-view-tabs',
321
+ } as const
322
+
323
+ export const sendTestEmailModalTestIds = {
324
+ modal: 'send-test-email-modal',
325
+ modalCloseButton: 'send-test-email-modal-close-button',
326
+ triggerButton: 'send-test-email-modal-trigger-button',
327
+ toFormField: 'send-test-email-modal-to-form-field',
328
+ toInput: 'send-test-email-modal-to-input',
329
+ cancelButton: 'send-test-email-modal-cancel-button',
330
+ sendButton: 'send-test-email-modal-send-button',
331
+ } as const
332
+
333
+ export const emailTranslationEditorTestIds = {
334
+ root: 'email-translation-editor',
335
+ subjectCard: 'email-translation-editor-subject-card',
336
+ baseSubjectPreview: 'email-translation-editor-base-subject-preview',
337
+ targetSubjectInput: 'email-translation-editor-target-subject-input',
338
+ emptyState: 'email-translation-editor-empty-state',
339
+ clearFiltersButton: 'email-translation-editor-clear-filters-button',
340
+ } as const
341
+
342
+ // ─── Whatsapp Editor ──────────────────────────────────────────────
343
+
344
+ export const whatsappEditorIndexTestIds = {
345
+ container: 'whatsapp-editor-index-container',
346
+ } as const
347
+
348
+ export const whatsappEditorBodyTestIds = {
349
+ container: 'whatsapp-editor-body-container',
350
+ contentEditor: 'whatsapp-editor-body-content-editor',
351
+ } as const
352
+
353
+ export const whatsappEditorButtonsTestIds = {
354
+ container: 'whatsapp-editor-buttons-container',
355
+ addButtonDropdown: 'whatsapp-editor-buttons-add-dropdown',
356
+ addButton: 'whatsapp-editor-buttons-add-button',
357
+ buttonItem: 'whatsapp-editor-buttons-item',
358
+ buttonTypeSelect: 'whatsapp-editor-buttons-type-select',
359
+ buttonTextField: 'whatsapp-editor-buttons-text-field',
360
+ buttonTextInput: 'whatsapp-editor-buttons-text-input',
361
+ buttonPhoneField: 'whatsapp-editor-buttons-phone-field',
362
+ buttonPhoneInput: 'whatsapp-editor-buttons-phone-input',
363
+ buttonUrlField: 'whatsapp-editor-buttons-url-field',
364
+ buttonUrlInput: 'whatsapp-editor-buttons-url-input',
365
+ buttonRemoveButton: 'whatsapp-editor-buttons-remove-button',
366
+ } as const
367
+
368
+ export const whatsappEditorFooterTestIds = {
369
+ container: 'whatsapp-editor-footer-container',
370
+ contentField: 'whatsapp-editor-footer-content-field',
371
+ contentInput: 'whatsapp-editor-footer-content-input',
372
+ } as const
373
+
374
+ export const whatsappEditorHeaderTestIds = {
375
+ container: 'whatsapp-editor-header-container',
376
+ typeSelect: 'whatsapp-editor-header-type-select',
377
+ textEditor: 'whatsapp-editor-header-text-editor',
378
+ mediaUpload: 'whatsapp-editor-header-media-upload',
379
+ mediaDeleteButton: 'whatsapp-editor-header-media-delete-button',
380
+ mediaRestoreButton: 'whatsapp-editor-header-media-restore-button',
381
+ } as const
382
+
383
+ export const whatsappEditorSyncWrapperTestIds = {
384
+ container: 'whatsapp-editor-sync-wrapper-container',
385
+ } as const
386
+
387
+ // ─── Whatsapp Translator ──────────────────────────────────────────
388
+
389
+ export const whatsappTranslatorIndexTestIds = {
390
+ container: 'whatsapp-translator-index-container',
391
+ sectionCard: 'whatsapp-translator-index-section-card',
392
+ } as const
393
+
394
+ export const whatsappTranslatorBodyTestIds = {
395
+ container: 'whatsapp-translator-body-container',
396
+ basePreview: 'whatsapp-translator-body-base-preview',
397
+ targetEditor: 'whatsapp-translator-body-target-editor',
398
+ } as const
399
+
400
+ export const whatsappTranslatorButtonTestIds = {
401
+ container: 'whatsapp-translator-button-container',
402
+ buttonItem: 'whatsapp-translator-button-item',
403
+ textField: 'whatsapp-translator-button-text-field',
404
+ textInput: 'whatsapp-translator-button-text-input',
405
+ urlField: 'whatsapp-translator-button-url-field',
406
+ urlInput: 'whatsapp-translator-button-url-input',
407
+ copyUrlButton: 'whatsapp-translator-button-copy-url',
408
+ phoneField: 'whatsapp-translator-button-phone-field',
409
+ phoneInput: 'whatsapp-translator-button-phone-input',
410
+ copyPhoneButton: 'whatsapp-translator-button-copy-phone',
411
+ } as const
412
+
413
+ export const whatsappTranslatorFooterTestIds = {
414
+ container: 'whatsapp-translator-footer-container',
415
+ basePreview: 'whatsapp-translator-footer-base-preview',
416
+ targetInput: 'whatsapp-translator-footer-target-input',
417
+ } as const
418
+
419
+ export const whatsappTranslatorHeaderTestIds = {
420
+ container: 'whatsapp-translator-header-container',
421
+ basePreview: 'whatsapp-translator-header-base-preview',
422
+ targetEditor: 'whatsapp-translator-header-target-editor',
423
+ } as const
424
+
425
+ export const whatsappTranslatorHeaderMediaTestIds = {
426
+ container: 'whatsapp-translator-header-media-container',
427
+ basePreview: 'whatsapp-translator-header-media-base-preview',
428
+ mediaUpload: 'whatsapp-translator-header-media-upload',
429
+ clearMediaButton: 'whatsapp-translator-header-media-clear-button',
430
+ resetTooltip: 'whatsapp-translator-header-media-reset-tooltip',
431
+ resetButton: 'whatsapp-translator-header-media-reset-button',
432
+ } as const
433
+
434
+ // ─── Whatsapp root ────────────────────────────────────────────────
435
+
436
+ export const categoryChangerTestIds = {
437
+ select: 'category-changer-select',
438
+ } as const
439
+
440
+ export const whatsappPreviewTestIds = {
441
+ container: 'whatsapp-preview-container',
442
+ chatWindow: 'whatsapp-preview-chat-window',
443
+ header: 'whatsapp-preview-header',
444
+ body: 'whatsapp-preview-body',
445
+ footer: 'whatsapp-preview-footer',
446
+ buttonsContainer: 'whatsapp-preview-buttons-container',
447
+ button: 'whatsapp-preview-button',
448
+ } as const
449
+
450
+ export const whatsappPreviewPanelTestIds = {
451
+ container: 'whatsapp-preview-panel-container',
452
+ } as const
453
+
454
+ export const whatsappTranslationEditorTestIds = {
455
+ container: 'whatsapp-translation-editor-container',
456
+ emptyState: 'whatsapp-translation-editor-empty-state',
457
+ clearFiltersButton: 'whatsapp-translation-editor-clear-filters-button',
458
+ } as const
459
+
460
+ // ─── Editor / TemplateList / Root ─────────────────────────────────
461
+
462
+ export const editorLinkPopoverTestIds = {
463
+ popover: 'editor-link-popover',
464
+ triggerButton: 'editor-link-popover-trigger-button',
465
+ urlInput: 'editor-link-popover-url-input',
466
+ applyButton: 'editor-link-popover-apply-button',
467
+ openButton: 'editor-link-popover-open-button',
468
+ removeButton: 'editor-link-popover-remove-button',
469
+ } as const
470
+
471
+ export const richTextEditorTestIds = {
472
+ root: 'rich-text-editor',
473
+ editor: 'rich-text-editor-editor',
474
+ toolbar: 'rich-text-editor-toolbar',
475
+ horizontalRuleButton: 'rich-text-editor-horizontal-rule-button',
476
+ improveButton: 'rich-text-editor-improve-button',
477
+ generateButton: 'rich-text-editor-generate-button',
478
+ } as const
479
+
480
+ export const aiGenerateSlideoverTestIds = {
481
+ slideover: 'ai-generate-slideover',
482
+ title: 'ai-generate-slideover-title',
483
+ description: 'ai-generate-slideover-description',
484
+ promptTextarea: 'ai-generate-slideover-prompt-textarea',
485
+ charCount: 'ai-generate-slideover-char-count',
486
+ disclaimer: 'ai-generate-slideover-disclaimer',
487
+ cancelButton: 'ai-generate-slideover-cancel-button',
488
+ submitButton: 'ai-generate-slideover-submit-button',
489
+ errorAlert: 'ai-generate-slideover-error-alert',
490
+ retryButton: 'ai-generate-slideover-retry-button',
491
+ yourRequest: 'ai-generate-slideover-your-request',
492
+ chooseOptionLabel: 'ai-generate-slideover-choose-option-label',
493
+ suggestionCard: 'ai-generate-slideover-suggestion-card',
494
+ suggestionContent: 'ai-generate-slideover-suggestion-content',
495
+ useItButton: 'ai-generate-slideover-use-it-button',
496
+ skeletonCard: 'ai-generate-slideover-skeleton-card',
497
+ createNewButton: 'ai-generate-slideover-create-new-button',
498
+ openButton: 'ai-generate-slideover-open-button',
499
+ closeButton: 'ai-generate-slideover-close-button',
500
+ } as const
501
+
502
+ export const templateListTableTestIds = {
503
+ root: 'template-list-table',
504
+ searchInput: 'template-list-table-search-input',
505
+ categorySelect: 'template-list-table-category-select',
506
+ statusSelect: 'template-list-table-status-select',
507
+ card: 'template-list-table-card',
508
+ table: 'template-list-table-table',
509
+ rowName: 'template-list-table-row-name',
510
+ rowInternalBadge: 'template-list-table-row-internal-badge',
511
+ rowCategoryBadge: 'template-list-table-row-category-badge',
512
+ rowPreview: 'template-list-table-row-preview',
513
+ rowActions: 'template-list-table-row-actions',
514
+ rowEditAction: 'template-list-table-row-edit',
515
+ rowDeleteAction: 'template-list-table-row-delete',
516
+ rowDuplicateAction: 'template-list-table-row-duplicate',
517
+ rowPublishAction: 'template-list-table-row-publish',
518
+ rowUnpublishAction: 'template-list-table-row-unpublish',
519
+ } as const
520
+
521
+ export const templateListStatusCellTestIds = {
522
+ root: 'template-list-status-cell',
523
+ tooltip: 'template-list-status-cell-tooltip',
524
+ tooltipContent: 'template-list-status-cell-tooltip-content',
525
+ badge: 'template-list-status-cell-badge',
526
+ } as const
527
+
528
+ export const dynamicDataButtonTestIds = {
529
+ triggerButton: 'dynamic-data-button-trigger-button',
530
+ modal: 'dynamic-data-button-modal',
531
+ modalCloseButton: 'dynamic-data-button-modal-close-button',
532
+ description: 'dynamic-data-button-description',
533
+ selectValueLabel: 'dynamic-data-button-select-value-label',
534
+ valueList: 'dynamic-data-button-value-list',
535
+ valueItem: 'dynamic-data-button-value-item',
536
+ } as const
537
+
538
+ export const dynamicDataSlideoverTestIds = {
539
+ triggerButton: 'dynamic-data-slideover-trigger-button',
540
+ slideover: 'dynamic-data-slideover',
541
+ description: 'dynamic-data-slideover-description',
542
+ tabs: 'dynamic-data-slideover-tabs',
543
+ listbox: 'dynamic-data-slideover-listbox',
544
+ closeButton: 'dynamic-data-slideover-close-button',
545
+ infoButton: 'dynamic-data-slideover-info-button',
546
+ } as const
547
+
548
+ // ─── Email Blocks ─────────────────────────────────────────────────
549
+
550
+ export const indexBlockTestIds = {
551
+ container: 'index-block-container',
552
+ duplicateButton: 'index-block-duplicate-button',
553
+ deleteButton: 'index-block-delete-button',
554
+ } as const
555
+
556
+ export const buttonBlockTestIds = {
557
+ container: 'button-block-container',
558
+ placeholder: 'button-block-placeholder',
559
+ button: 'button-block-button',
560
+ } as const
561
+
562
+ export const buttonSettingsTestIds = {
563
+ container: 'button-settings-container',
564
+ linkTypeField: 'button-settings-link-type-field',
565
+ linkTypeSelect: 'button-settings-link-type-select',
566
+ phoneInput: 'button-settings-phone-input',
567
+ urlInput: 'button-settings-url-input',
568
+ fontSizeField: 'button-settings-font-size-field',
569
+ fontSizeInput: 'button-settings-font-size-input',
570
+ shapeTabs: 'button-settings-shape-tabs',
571
+ widthTabs: 'button-settings-width-tabs',
572
+ alignmentTabs: 'button-settings-alignment-tabs',
573
+ } as const
574
+
575
+ export const discountCodeBlockTestIds = {
576
+ container: 'discount-code-block-container',
577
+ code: 'discount-code-block-code',
578
+ } as const
579
+
580
+ export const discountCodeSettingsTestIds = {
581
+ container: 'discount-code-settings-container',
582
+ fontSizeField: 'discount-code-settings-font-size-field',
583
+ fontSizeInput: 'discount-code-settings-font-size-input',
584
+ styleTabs: 'discount-code-settings-style-tabs',
585
+ widthTabs: 'discount-code-settings-width-tabs',
586
+ } as const
587
+
588
+ export const dividerBlockTestIds = {
589
+ container: 'divider-block-container',
590
+ rule: 'divider-block-rule',
591
+ } as const
592
+
593
+ export const dividerSettingsTestIds = {
594
+ container: 'divider-settings-container',
595
+ styleTabs: 'divider-settings-style-tabs',
596
+ thicknessField: 'divider-settings-thickness-field',
597
+ thicknessSlider: 'divider-settings-thickness-slider',
598
+ widthField: 'divider-settings-width-field',
599
+ widthInput: 'divider-settings-width-input',
600
+ resetButton: 'divider-settings-reset-button',
601
+ } as const
602
+
603
+ export const footerBlockTestIds = {
604
+ container: 'footer-block-container',
605
+ } as const
606
+
607
+ export const footerSettingsTestIds = {
608
+ container: 'footer-settings-container',
609
+ fontSizeField: 'footer-settings-font-size-field',
610
+ fontSizeInput: 'footer-settings-font-size-input',
611
+ } as const
612
+
613
+ export const gridBlockTestIds = {
614
+ container: 'grid-block-container',
615
+ column: 'grid-block-column',
616
+ addElementDropdown: 'grid-block-add-element-dropdown',
617
+ addElementButton: 'grid-block-add-element-button',
618
+ } as const
619
+
620
+ export const gridSettingsTestIds = {
621
+ container: 'grid-settings-container',
622
+ columnsTabs: 'grid-settings-columns-tabs',
623
+ } as const
624
+
625
+ export const headerBlockTestIds = {
626
+ container: 'header-block-container',
627
+ placeholder: 'header-block-placeholder',
628
+ logo: 'header-block-logo',
629
+ } as const
630
+
631
+ export const headerSettingsTestIds = {
632
+ container: 'header-settings-container',
633
+ altField: 'header-settings-alt-field',
634
+ altInput: 'header-settings-alt-input',
635
+ widthField: 'header-settings-width-field',
636
+ widthSlider: 'header-settings-width-slider',
637
+ alignmentTabs: 'header-settings-alignment-tabs',
638
+ } as const
639
+
640
+ export const headingBlockTestIds = {
641
+ container: 'heading-block-container',
642
+ } as const
643
+
644
+ export const headingSettingsTestIds = {
645
+ container: 'heading-settings-container',
646
+ tagSelect: 'heading-settings-tag-select',
647
+ fontSizeField: 'heading-settings-font-size-field',
648
+ fontSizeInput: 'heading-settings-font-size-input',
649
+ } as const
650
+
651
+ export const htmlBlockTestIds = {
652
+ container: 'html-block-container',
653
+ content: 'html-block-content',
654
+ placeholder: 'html-block-placeholder',
655
+ } as const
656
+
657
+ export const htmlSettingsTestIds = {
658
+ container: 'html-settings-container',
659
+ slideover: 'html-settings-slideover',
660
+ slideoverCloseButton: 'html-settings-slideover-close-button',
661
+ expandButton: 'html-settings-expand-button',
662
+ warningAlert: 'html-settings-warning-alert',
663
+ } as const
664
+
665
+ export const imageBlockTestIds = {
666
+ container: 'image-block-container',
667
+ placeholder: 'image-block-placeholder',
668
+ link: 'image-block-link',
669
+ image: 'image-block-image',
670
+ } as const
671
+
672
+ export const imageSettingsTestIds = {
673
+ container: 'image-settings-container',
674
+ linkField: 'image-settings-link-field',
675
+ linkInput: 'image-settings-link-input',
676
+ } as const
677
+
678
+ export const paragraphBlockTestIds = {
679
+ container: 'paragraph-block-container',
680
+ } as const
681
+
682
+ export const paragraphSettingsTestIds = {
683
+ container: 'paragraph-settings-container',
684
+ tagSelect: 'paragraph-settings-tag-select',
685
+ fontSizeField: 'paragraph-settings-font-size-field',
686
+ fontSizeInput: 'paragraph-settings-font-size-input',
687
+ } as const
688
+
689
+ export const socialsBlockTestIds = {
690
+ container: 'socials-block-container',
691
+ link: 'socials-block-link',
692
+ placeholder: 'socials-block-placeholder',
693
+ } as const
694
+
695
+ export const socialsSettingsTestIds = {
696
+ container: 'socials-settings-container',
697
+ toggleSwitch: 'socials-settings-toggle-switch',
698
+ urlInput: 'socials-settings-url-input',
699
+ } as const
700
+
701
+ export const spacerBlockTestIds = {
702
+ container: 'spacer-block-container',
703
+ } as const
704
+
705
+ export const spacerSettingsTestIds = {
706
+ container: 'spacer-settings-container',
707
+ sizePresetField: 'spacer-settings-size-preset-field',
708
+ sizePresetSelect: 'spacer-settings-size-preset-select',
709
+ customSizeSwitch: 'spacer-settings-custom-size-switch',
710
+ customSizeInput: 'spacer-settings-custom-size-input',
711
+ resetButton: 'spacer-settings-reset-button',
712
+ } as const
713
+
714
+ export const unsubscribeLinkBlockTestIds = {
715
+ container: 'unsubscribe-link-block-container',
716
+ editor: 'unsubscribe-link-block-editor',
717
+ placeholder: 'unsubscribe-link-block-placeholder',
718
+ } as const
719
+
720
+ export const unsubscribeLinkSettingsTestIds = {
721
+ container: 'unsubscribe-link-settings-container',
722
+ contentEditor: 'unsubscribe-link-settings-content-editor',
723
+ fontFamilySelect: 'unsubscribe-link-settings-font-family-select',
724
+ fontSizeField: 'unsubscribe-link-settings-font-size-field',
725
+ fontSizeInput: 'unsubscribe-link-settings-font-size-input',
726
+ textColorInput: 'unsubscribe-link-settings-text-color-input',
727
+ backgroundColorInput: 'unsubscribe-link-settings-background-color-input',
728
+ } as const