@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.
- package/README.md +75 -0
- package/app/api/ai.ts +28 -0
- package/app/api/brands.ts +54 -0
- package/app/api/client.ts +56 -0
- package/app/api/compilation.ts +34 -0
- package/app/api/dynamicValues.ts +11 -0
- package/app/api/index.ts +11 -0
- package/app/api/languages.ts +6 -0
- package/app/api/media.ts +26 -0
- package/app/api/messageGroups.ts +49 -0
- package/app/api/messages.ts +22 -0
- package/app/api/meta.ts +18 -0
- package/app/api/tracking.ts +9 -0
- package/app/components/Brand/BrandDrawer.vue +281 -0
- package/app/components/Brand/BrandPreview.vue +137 -0
- package/app/components/Brand/Steps/BrandStepGeneral.vue +37 -0
- package/app/components/Brand/Steps/BrandStepSocials.vue +48 -0
- package/app/components/Brand/Steps/BrandStepVisual.vue +214 -0
- package/app/components/Common/BrandColorSwatches.vue +37 -0
- package/app/components/Common/ColorInput.vue +144 -0
- package/app/components/Common/EmojiPickerButton.vue +35 -0
- package/app/components/Common/FontFamilySelect.vue +39 -0
- package/app/components/Common/HtmlPreviewIframe.vue +68 -0
- package/app/components/Common/IncompleteTranslationsDialog.vue +97 -0
- package/app/components/Common/LanguageList.vue +356 -0
- package/app/components/Common/LoadingOverlay.vue +12 -0
- package/app/components/Common/MediaUploadOrSelect.vue +299 -0
- package/app/components/Common/MessagePreviewSlideover.vue +88 -0
- package/app/components/Common/MonacoEditor.vue +110 -0
- package/app/components/Common/PhoneInput.vue +804 -0
- package/app/components/Common/SectionHeader.vue +26 -0
- package/app/components/Common/TranslationActionBar.vue +139 -0
- package/app/components/Common/ViewLessMore.vue +40 -0
- package/app/components/CreateTemplateButton.vue +59 -0
- package/app/components/DynamicDataButton.vue +75 -0
- package/app/components/DynamicDataSlideover.vue +149 -0
- package/app/components/Editor/AiGenerateSlideover.vue +292 -0
- package/app/components/Editor/EditorLinkPopover.vue +154 -0
- package/app/components/Editor/RichTextEditor.vue +495 -0
- package/app/components/Email/Editor/BlockLibrary.vue +89 -0
- package/app/components/Email/Editor/BlockSettings.vue +60 -0
- package/app/components/Email/Editor/Blocks/ButtonBlock.vue +117 -0
- package/app/components/Email/Editor/Blocks/ButtonSettings.vue +228 -0
- package/app/components/Email/Editor/Blocks/DiscountCodeBlock.vue +74 -0
- package/app/components/Email/Editor/Blocks/DiscountCodeSettings.vue +162 -0
- package/app/components/Email/Editor/Blocks/DividerBlock.vue +31 -0
- package/app/components/Email/Editor/Blocks/DividerSettings.vue +108 -0
- package/app/components/Email/Editor/Blocks/FooterBlock.vue +61 -0
- package/app/components/Email/Editor/Blocks/FooterSettings.vue +123 -0
- package/app/components/Email/Editor/Blocks/GridBlock.vue +128 -0
- package/app/components/Email/Editor/Blocks/GridSettings.vue +109 -0
- package/app/components/Email/Editor/Blocks/HTMLBlock.vue +31 -0
- package/app/components/Email/Editor/Blocks/HTMLSettings.vue +85 -0
- package/app/components/Email/Editor/Blocks/HeaderBlock.vue +53 -0
- package/app/components/Email/Editor/Blocks/HeaderSettings.vue +113 -0
- package/app/components/Email/Editor/Blocks/HeadingBlock.vue +61 -0
- package/app/components/Email/Editor/Blocks/HeadingSettings.vue +156 -0
- package/app/components/Email/Editor/Blocks/ImageBlock.vue +49 -0
- package/app/components/Email/Editor/Blocks/ImageSettings.vue +53 -0
- package/app/components/Email/Editor/Blocks/IndexBlock.vue +155 -0
- package/app/components/Email/Editor/Blocks/ParagraphBlock.vue +61 -0
- package/app/components/Email/Editor/Blocks/ParagraphSettings.vue +157 -0
- package/app/components/Email/Editor/Blocks/SocialsBlock.vue +63 -0
- package/app/components/Email/Editor/Blocks/SocialsSettings.vue +117 -0
- package/app/components/Email/Editor/Blocks/SpacerBlock.vue +37 -0
- package/app/components/Email/Editor/Blocks/SpacerSettings.vue +95 -0
- package/app/components/Email/Editor/Blocks/TopProductsBlock.vue +47 -0
- package/app/components/Email/Editor/Blocks/TopProductsSettings.vue +87 -0
- package/app/components/Email/Editor/Blocks/UnsubscribeLinkBlock.vue +61 -0
- package/app/components/Email/Editor/Blocks/UnsubscribeLinkSettings.vue +123 -0
- package/app/components/Email/Editor/Canvas.vue +143 -0
- package/app/components/Email/Editor/GeneralStyleSettings.vue +125 -0
- package/app/components/Email/Editor/Index.vue +77 -0
- package/app/components/Email/Editor/LeftSidebar.vue +95 -0
- package/app/components/Email/InlinePreview.vue +124 -0
- package/app/components/Email/Preview.vue +126 -0
- package/app/components/Email/PreviewPanel.vue +57 -0
- package/app/components/Email/SendTestEmailModal.vue +121 -0
- package/app/components/Email/TranslationEditor.vue +198 -0
- package/app/components/Email/Translator/Button.vue +101 -0
- package/app/components/Email/Translator/Discount.vue +60 -0
- package/app/components/Email/Translator/Footer.vue +66 -0
- package/app/components/Email/Translator/Grid.vue +127 -0
- package/app/components/Email/Translator/Header.vue +90 -0
- package/app/components/Email/Translator/Heading.vue +66 -0
- package/app/components/Email/Translator/Image.vue +91 -0
- package/app/components/Email/Translator/Index.vue +138 -0
- package/app/components/Email/Translator/Paragraph.vue +66 -0
- package/app/components/Email/Translator/RawHtml.vue +64 -0
- package/app/components/Email/Translator/UnsubscribeLink.vue +59 -0
- package/app/components/TemplateList/BaseTable.vue +354 -0
- package/app/components/TemplateList/StatusCell.vue +67 -0
- package/app/components/Whatsapp/CategoryChanger.vue +63 -0
- package/app/components/Whatsapp/Editor/Body.vue +53 -0
- package/app/components/Whatsapp/Editor/Buttons.vue +341 -0
- package/app/components/Whatsapp/Editor/Footer.vue +70 -0
- package/app/components/Whatsapp/Editor/Header.vue +156 -0
- package/app/components/Whatsapp/Editor/Index.vue +89 -0
- package/app/components/Whatsapp/Editor/SyncWrapper.vue +166 -0
- package/app/components/Whatsapp/Preview.vue +197 -0
- package/app/components/Whatsapp/PreviewPanel.vue +24 -0
- package/app/components/Whatsapp/TranslationEditor.vue +150 -0
- package/app/components/Whatsapp/Translator/Body.vue +61 -0
- package/app/components/Whatsapp/Translator/Button.vue +209 -0
- package/app/components/Whatsapp/Translator/Footer.vue +56 -0
- package/app/components/Whatsapp/Translator/Header.vue +61 -0
- package/app/components/Whatsapp/Translator/HeaderMedia.vue +117 -0
- package/app/components/Whatsapp/Translator/Index.vue +159 -0
- package/app/composables/composerContext.ts +35 -0
- package/app/composables/useAutoTranslate.ts +242 -0
- package/app/composables/useAutoTranslateEmail.ts +294 -0
- package/app/composables/useChangeTracking.ts +212 -0
- package/app/composables/useChangeTrackingEmail.ts +227 -0
- package/app/composables/useChannels.ts +36 -0
- package/app/composables/useEmailBlockContext.ts +43 -0
- package/app/composables/useExitConfirmation.ts +39 -0
- package/app/composables/useGoBack.ts +15 -0
- package/app/composables/useIncompleteTranslations.ts +55 -0
- package/app/composables/useIncompleteTranslationsEmail.ts +56 -0
- package/app/composables/useMediaLimits.ts +42 -0
- package/app/composables/useTemplateFormValidation.ts +109 -0
- package/app/composables/useTemplateOperations.ts +147 -0
- package/app/composables/useTracking.ts +39 -0
- package/app/composables/useTranslationFilters.ts +176 -0
- package/app/composables/useTranslationFiltersEmail.ts +244 -0
- package/app/composables/useWhatsappTemplateBehaviors.ts +58 -0
- package/app/middleware/channel-guard.ts +13 -0
- package/app/pages/brands.vue +195 -0
- package/app/pages/images.vue +141 -0
- package/app/pages/index.vue +198 -0
- package/app/pages/preview/[id].vue +47 -0
- package/app/pages/template/email/[id].vue +596 -0
- package/app/pages/template/email/create.vue +562 -0
- package/app/pages/template/whatsapp/[id].vue +561 -0
- package/app/pages/template/whatsapp/create.vue +468 -0
- package/app/plugins/admin-shortcut.client.ts +7 -0
- package/app/plugins/tracking.client.ts +12 -0
- package/app/queries/ai.ts +20 -0
- package/app/queries/brands.ts +75 -0
- package/app/queries/compilation.ts +37 -0
- package/app/queries/dynamicValues.ts +13 -0
- package/app/queries/index.ts +9 -0
- package/app/queries/languages.ts +10 -0
- package/app/queries/media.ts +27 -0
- package/app/queries/messageGroups.ts +112 -0
- package/app/queries/messages.ts +42 -0
- package/app/queries/meta.ts +13 -0
- package/app/stores/adminStore.ts +50 -0
- package/app/stores/appContext.ts +99 -0
- package/app/stores/emailEditor.ts +220 -0
- package/app/stores/main.ts +3 -0
- package/app/stores/metaSubmission.ts +116 -0
- package/app/types/app-config.d.ts +14 -0
- package/app/types/hooks.d.ts +9 -0
- package/app/types/tracking.ts +148 -0
- package/app/utils/locale.ts +17 -0
- package/app/utils/notifyParent.ts +7 -0
- package/app/utils/resolveDefaultLanguage.ts +14 -0
- package/app/utils/socialDefaults.ts +42 -0
- package/app/utils/testIds.const.ts +728 -0
- package/app.config.ts +5 -0
- package/i18n/check-translations.ts +56 -0
- package/i18n/locales/de.ts +834 -0
- package/i18n/locales/en.ts +826 -0
- package/i18n/locales/es.ts +833 -0
- package/i18n/locales/fr.ts +837 -0
- package/i18n/locales/it.ts +831 -0
- package/nuxt.config.ts +65 -0
- package/package.json +64 -0
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
export type MessagesKind = 'email' | 'whatsapp'
|
|
2
|
+
|
|
3
|
+
export interface MessageActionProperties {
|
|
4
|
+
message_name: string
|
|
5
|
+
languages: string[]
|
|
6
|
+
message_id: string
|
|
7
|
+
message_kind: MessagesKind
|
|
8
|
+
message_category: string
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// ── WhatsApp shared property interfaces ──
|
|
12
|
+
|
|
13
|
+
export type WaHeaderType = 'none' | 'text' | 'video' | 'image' | 'document'
|
|
14
|
+
|
|
15
|
+
export interface WaBaseProperties {
|
|
16
|
+
name: string
|
|
17
|
+
category: string
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface WaDraftProperties extends WaBaseProperties {
|
|
21
|
+
languages: string[]
|
|
22
|
+
header: WaHeaderType
|
|
23
|
+
footer: boolean
|
|
24
|
+
buttons: number
|
|
25
|
+
is_internal: boolean
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface WaLanguageProperties extends WaBaseProperties {
|
|
29
|
+
language: string
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface WaTranslationsFiltersProperties extends WaLanguageProperties {
|
|
33
|
+
search_term: string
|
|
34
|
+
show_only_missing: boolean
|
|
35
|
+
show_only_changes: boolean
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// ── Email shared property interfaces ──
|
|
39
|
+
|
|
40
|
+
export interface EmailBaseProperties {
|
|
41
|
+
name: string
|
|
42
|
+
subject: string
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface EmailDraftProperties extends EmailBaseProperties {
|
|
46
|
+
languages: string[]
|
|
47
|
+
widgets: string[]
|
|
48
|
+
is_internal: boolean
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface EmailLanguageProperties extends EmailBaseProperties {
|
|
52
|
+
language: string
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export interface EmailTranslationsFiltersProperties extends EmailLanguageProperties {
|
|
56
|
+
search_term: string
|
|
57
|
+
show_only_missing: boolean
|
|
58
|
+
show_only_changes: boolean
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// ── Event map ──
|
|
62
|
+
|
|
63
|
+
export interface TrackingEventMap {
|
|
64
|
+
// === Global ===
|
|
65
|
+
'Page View': { page_name: string }
|
|
66
|
+
|
|
67
|
+
// === Table_List ===
|
|
68
|
+
change_filters: {
|
|
69
|
+
search_term: string
|
|
70
|
+
category: string
|
|
71
|
+
status: string
|
|
72
|
+
messages_kind: MessagesKind
|
|
73
|
+
}
|
|
74
|
+
change_tab: { messages_kind: MessagesKind }
|
|
75
|
+
message_create: { message_kind: MessagesKind }
|
|
76
|
+
message_delete: MessageActionProperties
|
|
77
|
+
message_duplicate: MessageActionProperties
|
|
78
|
+
message_edit: MessageActionProperties
|
|
79
|
+
table_sorting: { messages_kind: MessagesKind; sort_column: string }
|
|
80
|
+
|
|
81
|
+
// === Whatsapp_create ===
|
|
82
|
+
'wa_create.save_draft': WaDraftProperties
|
|
83
|
+
'wa_create.request_approval': WaDraftProperties
|
|
84
|
+
'wa_create.add_language': WaLanguageProperties
|
|
85
|
+
'wa_create.remove_language': WaLanguageProperties
|
|
86
|
+
'wa_create.auto_translate': WaLanguageProperties
|
|
87
|
+
'wa_create.preview': WaLanguageProperties
|
|
88
|
+
'wa_create.translations_filters': WaTranslationsFiltersProperties
|
|
89
|
+
'wa_create.change_tab': WaBaseProperties & { tab: string }
|
|
90
|
+
|
|
91
|
+
// === Whatsapp_edit ===
|
|
92
|
+
'wa_edit.save_as_new': WaDraftProperties
|
|
93
|
+
'wa_edit.request_approval': WaDraftProperties
|
|
94
|
+
'wa_edit.add_language': WaLanguageProperties
|
|
95
|
+
'wa_edit.remove_language': WaLanguageProperties
|
|
96
|
+
'wa_edit.auto_translate': WaLanguageProperties
|
|
97
|
+
'wa_edit.preview': WaLanguageProperties
|
|
98
|
+
'wa_edit.translations_filters': WaTranslationsFiltersProperties
|
|
99
|
+
'wa_edit.change_tab': WaBaseProperties & { tab: string }
|
|
100
|
+
|
|
101
|
+
// === Email_create ===
|
|
102
|
+
'email_create.save_draft': EmailDraftProperties
|
|
103
|
+
'email_create.save': EmailDraftProperties
|
|
104
|
+
'email_create.add_language': EmailLanguageProperties
|
|
105
|
+
'email_create.remove_language': EmailLanguageProperties
|
|
106
|
+
'email_create.auto_translate': EmailLanguageProperties
|
|
107
|
+
'email_create.preview': EmailLanguageProperties
|
|
108
|
+
'email_create.translations_filters': EmailTranslationsFiltersProperties
|
|
109
|
+
'email_create.change_tab': EmailBaseProperties & { tab: string }
|
|
110
|
+
'email_create.add_widget': EmailBaseProperties & { widget_type: string; adding_mode: string }
|
|
111
|
+
'email_create.remove_widget': EmailBaseProperties & { widget_type: string }
|
|
112
|
+
'email_create.sort_widget': EmailBaseProperties & {
|
|
113
|
+
widget_type: string
|
|
114
|
+
before_sort_position: number
|
|
115
|
+
new_position: number
|
|
116
|
+
}
|
|
117
|
+
'email_create.duplicate_widget': EmailBaseProperties & { widget_type: string }
|
|
118
|
+
'email_create.change_widget_tab': EmailBaseProperties & { tab: string }
|
|
119
|
+
'email_create.send_test': EmailBaseProperties & {
|
|
120
|
+
widgets: string[]
|
|
121
|
+
to_recipients: number
|
|
122
|
+
language: string
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// === Email_edit ===
|
|
126
|
+
'email_edit.save_draft': EmailDraftProperties
|
|
127
|
+
'email_edit.save': EmailDraftProperties
|
|
128
|
+
'email_edit.add_language': EmailLanguageProperties
|
|
129
|
+
'email_edit.remove_language': EmailLanguageProperties
|
|
130
|
+
'email_edit.auto_translate': EmailLanguageProperties
|
|
131
|
+
'email_edit.preview': EmailLanguageProperties
|
|
132
|
+
'email_edit.translations_filters': EmailTranslationsFiltersProperties
|
|
133
|
+
'email_edit.change_tab': EmailBaseProperties & { tab: string }
|
|
134
|
+
'email_edit.add_widget': EmailBaseProperties & { widget_type: string; adding_mode: string }
|
|
135
|
+
'email_edit.remove_widget': EmailBaseProperties & { widget_type: string }
|
|
136
|
+
'email_edit.sort_widget': EmailBaseProperties & {
|
|
137
|
+
widget_type: string
|
|
138
|
+
before_sort_position: number
|
|
139
|
+
new_position: number
|
|
140
|
+
}
|
|
141
|
+
'email_edit.duplicate_widget': EmailBaseProperties & { widget_type: string }
|
|
142
|
+
'email_edit.change_widget_tab': EmailBaseProperties & { tab: string }
|
|
143
|
+
'email_edit.send_test': EmailBaseProperties & {
|
|
144
|
+
widgets: string[]
|
|
145
|
+
to_recipients: number
|
|
146
|
+
language: string
|
|
147
|
+
}
|
|
148
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { managedLocales, type ManagedLocales } from '@dev.smartpricing/message-composer-utils/types'
|
|
2
|
+
|
|
3
|
+
export function isLocaleManaged(locale: string): locale is ManagedLocales {
|
|
4
|
+
return managedLocales.includes(locale as ManagedLocales)
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export async function extractFromLocale(key: string, locale: string): Promise<string> {
|
|
8
|
+
const nuxtApp = useNuxtApp()
|
|
9
|
+
const { t, loadLocaleMessages } = nuxtApp.$i18n
|
|
10
|
+
let _locale: ManagedLocales = 'en'
|
|
11
|
+
if (isLocaleManaged(locale)) {
|
|
12
|
+
_locale = locale
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
await loadLocaleMessages(_locale)
|
|
16
|
+
return t(key, 1, { locale: _locale })
|
|
17
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { toRaw } from 'vue'
|
|
2
|
+
import { deepClone } from '@dev.smartpricing/message-composer-utils/utils'
|
|
3
|
+
import type { ParentNotificationType } from '@dev.smartpricing/message-composer-utils/types'
|
|
4
|
+
|
|
5
|
+
export function notifyParent(type: ParentNotificationType, data?: Record<string, unknown>) {
|
|
6
|
+
window.parent.postMessage({ type, data: data ? deepClone(toRaw(data)) : undefined }, '*')
|
|
7
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolves the default language to display from a messages record.
|
|
3
|
+
* Fallback chain: mainLanguage → 'en' → first available key → undefined
|
|
4
|
+
*/
|
|
5
|
+
export function resolveDefaultLanguage(
|
|
6
|
+
messages: Record<string, unknown>,
|
|
7
|
+
mainLanguage: string,
|
|
8
|
+
): string | undefined {
|
|
9
|
+
if (messages[mainLanguage]) return mainLanguage
|
|
10
|
+
if (messages['en']) return 'en'
|
|
11
|
+
|
|
12
|
+
const keys = Object.keys(messages)
|
|
13
|
+
return keys.length > 0 ? keys[0] : undefined
|
|
14
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
BrandSocials,
|
|
3
|
+
SocialLink,
|
|
4
|
+
SocialPlatform,
|
|
5
|
+
} from '@dev.smartpricing/message-composer-utils/types'
|
|
6
|
+
import { SOCIAL_PLATFORMS } from '@dev.smartpricing/message-composer-utils/types'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Builds block-level socials from brand defaults:
|
|
10
|
+
* - Platforms with a brand URL → enabled, empty url (cascades from brand)
|
|
11
|
+
* - Platforms without → disabled, empty url
|
|
12
|
+
*/
|
|
13
|
+
export function applySocialDefaults(
|
|
14
|
+
brandSocials: BrandSocials | null,
|
|
15
|
+
): Record<SocialPlatform, SocialLink> {
|
|
16
|
+
const result = {} as Record<SocialPlatform, SocialLink>
|
|
17
|
+
for (const platform of SOCIAL_PLATFORMS) {
|
|
18
|
+
const hasBrandUrl = !!brandSocials?.[platform]
|
|
19
|
+
result[platform] = { enabled: hasBrandUrl, url: '' }
|
|
20
|
+
}
|
|
21
|
+
return result
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Normalizes brand socials from DB, handling old {enabled, url} format
|
|
26
|
+
* and converting to new string-only format.
|
|
27
|
+
*/
|
|
28
|
+
export function normalizeBrandSocials(
|
|
29
|
+
raw: Record<string, unknown> | null | undefined,
|
|
30
|
+
): BrandSocials | null {
|
|
31
|
+
if (!raw) return null
|
|
32
|
+
const result: BrandSocials = {}
|
|
33
|
+
for (const [key, value] of Object.entries(raw)) {
|
|
34
|
+
if (typeof value === 'string' && value) {
|
|
35
|
+
result[key as SocialPlatform] = value
|
|
36
|
+
} else if (value && typeof value === 'object' && 'url' in value) {
|
|
37
|
+
const url = (value as { url: string }).url
|
|
38
|
+
if (url) result[key as SocialPlatform] = url
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return Object.keys(result).length > 0 ? result : null
|
|
42
|
+
}
|