@dev.smartpricing/message-composer-layer 4.2.11-ux.0 → 4.2.11-ux.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/app/api/meta.ts +9 -0
- package/app/components/Brand/BrandDrawer.vue +1 -0
- package/app/components/Brand/Steps/BrandStepVisual.vue +6 -1
- package/app/components/Common/LanguageList.vue +55 -1
- package/app/components/Composer/WhatsappComposer.vue +32 -1
- package/app/components/Composer/WhatsappTranslations.vue +2 -0
- package/app/components/Editor/RichTextEditor.vue +9 -4
- package/app/components/Email/Editor/Blocks/FooterBlock.vue +2 -0
- package/app/components/Email/Editor/Blocks/FooterSettings.vue +34 -0
- package/app/components/Email/Editor/Blocks/HeadingBlock.vue +2 -0
- package/app/components/Email/Editor/Blocks/HeadingSettings.vue +34 -0
- package/app/components/Email/Editor/Blocks/ParagraphBlock.vue +2 -0
- package/app/components/Email/Editor/Blocks/ParagraphSettings.vue +34 -0
- package/app/components/Email/Editor/Blocks/UnsubscribeLinkBlock.vue +2 -0
- package/app/components/Email/Editor/Blocks/UnsubscribeLinkSettings.vue +33 -0
- package/app/stores/metaSubmission.ts +26 -0
- package/app/types/tracking.ts +1 -0
- package/app/utils/testIds.const.ts +9 -0
- package/i18n/locales/de.ts +12 -0
- package/i18n/locales/en.ts +12 -0
- package/i18n/locales/es.ts +12 -0
- package/i18n/locales/fr.ts +12 -0
- package/i18n/locales/it.ts +12 -0
- package/package.json +2 -2
package/app/api/meta.ts
CHANGED
|
@@ -11,6 +11,15 @@ export const metaApi = {
|
|
|
11
11
|
body: {},
|
|
12
12
|
}),
|
|
13
13
|
|
|
14
|
+
submitMessage: (messageId: string) =>
|
|
15
|
+
apiClient<{ success: boolean; templateId?: string }>(
|
|
16
|
+
`/integrations/meta/submit-message/${messageId}`,
|
|
17
|
+
{
|
|
18
|
+
method: 'POST',
|
|
19
|
+
body: {},
|
|
20
|
+
},
|
|
21
|
+
),
|
|
22
|
+
|
|
14
23
|
getJobStatus: (jobId: string) =>
|
|
15
24
|
apiClient<SubmissionJob>(`/integrations/meta/submission-jobs/${jobId}`, {
|
|
16
25
|
method: 'GET',
|
|
@@ -169,7 +169,7 @@ function removeColor(index: number) {
|
|
|
169
169
|
<!-- Default email colors -->
|
|
170
170
|
<div class="space-y-2">
|
|
171
171
|
<p class="text-sm font-medium">{{ $t('pages.brands.fields.default_email_colors') }}</p>
|
|
172
|
-
<div class="grid grid-cols-1 sm:grid-cols-
|
|
172
|
+
<div class="grid grid-cols-1 sm:grid-cols-2 gap-3">
|
|
173
173
|
<ColorInput
|
|
174
174
|
:brand-colors="colors"
|
|
175
175
|
v-model="defaultEmailSettings.backgroundColor"
|
|
@@ -185,6 +185,11 @@ function removeColor(index: number) {
|
|
|
185
185
|
v-model="defaultEmailSettings.textColor"
|
|
186
186
|
:label="$t('pages.brands.fields.email_text_color')"
|
|
187
187
|
/>
|
|
188
|
+
<ColorInput
|
|
189
|
+
:brand-colors="colors"
|
|
190
|
+
v-model="defaultEmailSettings.linkColor"
|
|
191
|
+
:label="$t('pages.brands.fields.email_link_color')"
|
|
192
|
+
/>
|
|
188
193
|
</div>
|
|
189
194
|
</div>
|
|
190
195
|
|
|
@@ -57,6 +57,14 @@
|
|
|
57
57
|
name="ph:check-circle-fill"
|
|
58
58
|
class="text-success-500 w-4 h-4"
|
|
59
59
|
/>
|
|
60
|
+
<UBadge
|
|
61
|
+
v-if="getMessageStatus(lang.id)"
|
|
62
|
+
:color="statusColor(getMessageStatus(lang.id)!)"
|
|
63
|
+
variant="subtle"
|
|
64
|
+
size="sm"
|
|
65
|
+
>
|
|
66
|
+
{{ t(`status.${getMessageStatus(lang.id)}`) }}
|
|
67
|
+
</UBadge>
|
|
60
68
|
</div>
|
|
61
69
|
</div>
|
|
62
70
|
<div class="flex items-center gap-2">
|
|
@@ -71,6 +79,16 @@
|
|
|
71
79
|
}}
|
|
72
80
|
</span>
|
|
73
81
|
</div>
|
|
82
|
+
<UButton
|
|
83
|
+
v-if="canRequestReview(lang.id)"
|
|
84
|
+
size="sm"
|
|
85
|
+
@click.stop="emit('requestReview', lang.id)"
|
|
86
|
+
color="primary"
|
|
87
|
+
variant="ghost"
|
|
88
|
+
icon="ph:paper-plane-tilt"
|
|
89
|
+
:title="t('language_list.request_review')"
|
|
90
|
+
:data-testid="`${languageListTestIds.requestReviewButton}-${lang.id}`"
|
|
91
|
+
/>
|
|
74
92
|
<UButton
|
|
75
93
|
size="sm"
|
|
76
94
|
:disabled="grouped.used.length <= 1 || lang.id === 'en' || lang.id === mainLanguageId"
|
|
@@ -134,7 +152,12 @@ const availableLanguages = computed(() => {
|
|
|
134
152
|
if (!languages.value) return { recommended: [], others: [] }
|
|
135
153
|
|
|
136
154
|
const used = Object.keys(messages.value)
|
|
137
|
-
|
|
155
|
+
let unused = languages.value.filter((lang) => !used.includes(lang.id))
|
|
156
|
+
|
|
157
|
+
// WhatsApp templates only support Meta-mapped languages; hide the rest
|
|
158
|
+
if (props.renderType === 'whatsapp_v1') {
|
|
159
|
+
unused = unused.filter((lang) => lang.meta_language_code != null)
|
|
160
|
+
}
|
|
138
161
|
|
|
139
162
|
const recommended = unused.filter((lang) => appContext.languages.includes(lang.id))
|
|
140
163
|
const others = unused.filter((lang) => !appContext.languages.includes(lang.id))
|
|
@@ -225,8 +248,39 @@ const language = defineModel<string>('language', {
|
|
|
225
248
|
const emit = defineEmits<{
|
|
226
249
|
addLanguage: [languageId: string]
|
|
227
250
|
removeLanguage: [languageId: string]
|
|
251
|
+
requestReview: [languageId: string]
|
|
228
252
|
}>()
|
|
229
253
|
|
|
254
|
+
// ── Per-message Meta review status (WhatsApp only) ────────────────
|
|
255
|
+
// Only surfaced for persisted (saved) WhatsApp messages — unsaved drafts in
|
|
256
|
+
// create mode / newly added languages have no Meta status to show yet.
|
|
257
|
+
function getMessageStatus(languageId: string): string | undefined {
|
|
258
|
+
const message = messages.value[languageId]
|
|
259
|
+
if (!message || message.render_type !== 'whatsapp_v1') return undefined
|
|
260
|
+
if (!('id' in message) || !message.id) return undefined
|
|
261
|
+
return message.status as string | undefined
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// Mirrors the group rule, minus approved (approved is terminal here):
|
|
265
|
+
// a saved WhatsApp language can request review while draft or rejected.
|
|
266
|
+
function canRequestReview(languageId: string): boolean {
|
|
267
|
+
const status = getMessageStatus(languageId)
|
|
268
|
+
return status === 'draft' || status === 'rejected'
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
function statusColor(status: string) {
|
|
272
|
+
switch (status) {
|
|
273
|
+
case 'approved':
|
|
274
|
+
return 'success' as const
|
|
275
|
+
case 'pending':
|
|
276
|
+
return 'warning' as const
|
|
277
|
+
case 'rejected':
|
|
278
|
+
return 'error' as const
|
|
279
|
+
default:
|
|
280
|
+
return 'neutral' as const
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
230
284
|
// Helper functions for change tracking
|
|
231
285
|
function hasLanguageChanges(languageId: string): boolean {
|
|
232
286
|
const message = messages.value[languageId]
|
|
@@ -9,6 +9,7 @@ import type {
|
|
|
9
9
|
import { useAppContextStore } from '@/stores/appContext'
|
|
10
10
|
import { useMetaSubmissionStore } from '@/stores/metaSubmission'
|
|
11
11
|
import { useMessageGroupQuery, useLanguagesQuery } from '~/queries'
|
|
12
|
+
import { messagesApi } from '~/api/messages'
|
|
12
13
|
import type { WaHeaderType } from '~/types/tracking'
|
|
13
14
|
|
|
14
15
|
const props = defineProps<{
|
|
@@ -25,7 +26,9 @@ const store = useWhatsappComposerStore()
|
|
|
25
26
|
const { mainLanguage } = storeToRefs(useAppContextStore())
|
|
26
27
|
const { trackEvent } = useTracking()
|
|
27
28
|
const { goBackOrFallback } = useGoBack()
|
|
28
|
-
const { submitToMeta } = useMetaSubmissionStore()
|
|
29
|
+
const { submitToMeta, submitMessageToMeta } = useMetaSubmissionStore()
|
|
30
|
+
const { confirm } = useConfirm()
|
|
31
|
+
const { t } = useI18n()
|
|
29
32
|
|
|
30
33
|
// ── Init ──────────────────────────────────────────────────────────
|
|
31
34
|
if (props.mode === 'create') {
|
|
@@ -260,6 +263,33 @@ async function requestApproval() {
|
|
|
260
263
|
}
|
|
261
264
|
}
|
|
262
265
|
|
|
266
|
+
// ── Per-language review request ───────────────────────────────────
|
|
267
|
+
async function onRequestReview(languageId: string) {
|
|
268
|
+
const message = store.messages[languageId] as (WhatsappMessage & { id?: string }) | undefined
|
|
269
|
+
if (!message?.id) return
|
|
270
|
+
|
|
271
|
+
const languageName = languages.value?.find((l) => l.id === languageId)?.name ?? languageId
|
|
272
|
+
|
|
273
|
+
confirm({
|
|
274
|
+
title: t('dialogs.request_review.title'),
|
|
275
|
+
message: t('dialogs.request_review.message', { language: languageName }),
|
|
276
|
+
confirmProps: { label: t('dialogs.request_review.confirm') },
|
|
277
|
+
cancelProps: { label: t('common.actions.cancel') },
|
|
278
|
+
action: async () => {
|
|
279
|
+
// Decision C: persist only this language's current edits, then submit it.
|
|
280
|
+
await messagesApi.update(message.id!, message)
|
|
281
|
+
await submitMessageToMeta(message.id!)
|
|
282
|
+
// Reflect pending locally instead of refetching the group, so unsaved
|
|
283
|
+
// edits in other languages are preserved.
|
|
284
|
+
store.messages[languageId] = { ...message, status: 'pending' }
|
|
285
|
+
track('request_review_language', {
|
|
286
|
+
...getWaBaseProps(),
|
|
287
|
+
language: languageId,
|
|
288
|
+
})
|
|
289
|
+
},
|
|
290
|
+
})
|
|
291
|
+
}
|
|
292
|
+
|
|
263
293
|
// ── Public action handlers ────────────────────────────────────────
|
|
264
294
|
async function handleSaveDraft() {
|
|
265
295
|
if (!(await validateDraft())) return
|
|
@@ -420,6 +450,7 @@ defineExpose({
|
|
|
420
450
|
:mode="mode"
|
|
421
451
|
@add-language="onAddLanguage"
|
|
422
452
|
@remove-language="onRemoveLanguage"
|
|
453
|
+
@request-review="onRequestReview"
|
|
423
454
|
@auto-translate-tracked="onAutoTranslateTracked"
|
|
424
455
|
@preview="onPreview"
|
|
425
456
|
@filters-changed="onFiltersChanged"
|
|
@@ -10,6 +10,7 @@ const props = defineProps<{
|
|
|
10
10
|
const emit = defineEmits<{
|
|
11
11
|
'add-language': [lang: string]
|
|
12
12
|
'remove-language': [lang: string]
|
|
13
|
+
'request-review': [lang: string]
|
|
13
14
|
'auto-translate-tracked': [lang: string]
|
|
14
15
|
preview: [lang: string]
|
|
15
16
|
'filters-changed': [
|
|
@@ -49,6 +50,7 @@ const testIds = computed(() =>
|
|
|
49
50
|
:main-language-id="store.language"
|
|
50
51
|
@add-language="emit('add-language', $event)"
|
|
51
52
|
@remove-language="emit('remove-language', $event)"
|
|
53
|
+
@request-review="emit('request-review', $event)"
|
|
52
54
|
/>
|
|
53
55
|
</div>
|
|
54
56
|
<div class="overflow-y-auto" v-if="store.currentMessage && store.targetMessage">
|
|
@@ -9,6 +9,7 @@ import type {
|
|
|
9
9
|
RefineTextResponse,
|
|
10
10
|
} from '@dev.smartpricing/message-composer-utils/types'
|
|
11
11
|
import {
|
|
12
|
+
buildLinkHTMLAttributes,
|
|
12
13
|
convertToWhatsappMarkdown,
|
|
13
14
|
getTipTapExtensions,
|
|
14
15
|
sanitizeContent,
|
|
@@ -39,6 +40,7 @@ const props = withDefaults(
|
|
|
39
40
|
horizontalRule?: boolean
|
|
40
41
|
alignment?: boolean
|
|
41
42
|
link?: boolean
|
|
43
|
+
linkColor?: string
|
|
42
44
|
emoji?: boolean
|
|
43
45
|
}>(),
|
|
44
46
|
{
|
|
@@ -134,9 +136,12 @@ const starterKitConfig = computed(() => {
|
|
|
134
136
|
link: props.link
|
|
135
137
|
? {
|
|
136
138
|
openOnClick: false,
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
139
|
+
// Callers that don't opt in with `linkColor` (e.g. ButtonSettings, whose
|
|
140
|
+
// links aren't part of the block-level linkColor feature) keep the old
|
|
141
|
+
// fixed styling instead of an unset `--link-color` custom property.
|
|
142
|
+
HTMLAttributes: props.linkColor
|
|
143
|
+
? { class: 'underline', ...buildLinkHTMLAttributes({ mode: 'live' }) }
|
|
144
|
+
: { class: 'text-primary-600 underline' },
|
|
140
145
|
}
|
|
141
146
|
: false,
|
|
142
147
|
heading: false,
|
|
@@ -373,7 +378,7 @@ defineExpose({
|
|
|
373
378
|
</script>
|
|
374
379
|
|
|
375
380
|
<template>
|
|
376
|
-
<div :data-testid="richTextEditorTestIds.root">
|
|
381
|
+
<div :data-testid="richTextEditorTestIds.root" :style="{ '--link-color': linkColor }">
|
|
377
382
|
<div class="rounded-md border border-accented overflow-hidden">
|
|
378
383
|
<UEditor
|
|
379
384
|
ref="editorRef"
|
|
@@ -18,6 +18,7 @@ const editor = useEditor({
|
|
|
18
18
|
extensions: getTipTapExtensions({
|
|
19
19
|
preset: 'email',
|
|
20
20
|
dynamicValues: true,
|
|
21
|
+
linkColor: { mode: 'live' },
|
|
21
22
|
}),
|
|
22
23
|
})
|
|
23
24
|
|
|
@@ -47,6 +48,7 @@ defineOptions({
|
|
|
47
48
|
fontFamily: block.settings.fontFamily ?? emailEditorStore.resolvedSettings.fontFamily,
|
|
48
49
|
fontSize: `${block.settings.fontSize}px`,
|
|
49
50
|
color: block.settings.textColor ?? emailEditorStore.resolvedSettings.textColor,
|
|
51
|
+
'--link-color': block.settings.linkColor ?? emailEditorStore.resolvedSettings.linkColor,
|
|
50
52
|
}"
|
|
51
53
|
>
|
|
52
54
|
<EditorContent :editor="editor" class="pointer-events-none" />
|
|
@@ -23,6 +23,19 @@ const content = computed({
|
|
|
23
23
|
},
|
|
24
24
|
})
|
|
25
25
|
|
|
26
|
+
const resolvedLinkColor = computed(
|
|
27
|
+
() => props.block.settings.linkColor ?? emailEditorStore.resolvedSettings.linkColor,
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
function matchTextColor() {
|
|
31
|
+
emailEditorStore.updateBlock(props.block.id, {
|
|
32
|
+
settings: {
|
|
33
|
+
...props.block.settings,
|
|
34
|
+
linkColor: props.block.settings.textColor ?? emailEditorStore.resolvedSettings.textColor,
|
|
35
|
+
},
|
|
36
|
+
})
|
|
37
|
+
}
|
|
38
|
+
|
|
26
39
|
function resetTextStyle() {
|
|
27
40
|
emailEditorStore.updateBlock(props.block.id, {
|
|
28
41
|
settings: {
|
|
@@ -38,6 +51,7 @@ function resetColors() {
|
|
|
38
51
|
settings: {
|
|
39
52
|
...props.block.settings,
|
|
40
53
|
textColor: DEFAULT_FOOTER_SETTINGS.textColor,
|
|
54
|
+
linkColor: DEFAULT_FOOTER_SETTINGS.linkColor,
|
|
41
55
|
backgroundColor: DEFAULT_FOOTER_SETTINGS.backgroundColor,
|
|
42
56
|
},
|
|
43
57
|
})
|
|
@@ -63,6 +77,7 @@ defineOptions({
|
|
|
63
77
|
underline
|
|
64
78
|
alignment
|
|
65
79
|
link
|
|
80
|
+
:link-color="resolvedLinkColor"
|
|
66
81
|
emoji
|
|
67
82
|
dynamic-values
|
|
68
83
|
/>
|
|
@@ -113,6 +128,25 @@ defineOptions({
|
|
|
113
128
|
:default-value="emailEditorStore.resolvedSettings.textColor"
|
|
114
129
|
/>
|
|
115
130
|
|
|
131
|
+
<!-- Link Color -->
|
|
132
|
+
<ColorInput
|
|
133
|
+
v-model="block.settings.linkColor"
|
|
134
|
+
:label="$t('editor.email.blocks.heading.settings.link')"
|
|
135
|
+
:default-value="emailEditorStore.resolvedSettings.linkColor"
|
|
136
|
+
:data-testid="footerSettingsTestIds.linkColorInput"
|
|
137
|
+
>
|
|
138
|
+
<template #trailing>
|
|
139
|
+
<UButton
|
|
140
|
+
size="xs"
|
|
141
|
+
color="neutral"
|
|
142
|
+
variant="ghost"
|
|
143
|
+
:label="$t('editor.email.blocks.heading.settings.match_text_color')"
|
|
144
|
+
:data-testid="footerSettingsTestIds.matchTextColorButton"
|
|
145
|
+
@click.stop="matchTextColor"
|
|
146
|
+
/>
|
|
147
|
+
</template>
|
|
148
|
+
</ColorInput>
|
|
149
|
+
|
|
116
150
|
<!-- Background Color -->
|
|
117
151
|
<ColorInput
|
|
118
152
|
v-model="block.settings.backgroundColor"
|
|
@@ -18,6 +18,7 @@ const editor = useEditor({
|
|
|
18
18
|
extensions: getTipTapExtensions({
|
|
19
19
|
preset: 'email',
|
|
20
20
|
dynamicValues: true,
|
|
21
|
+
linkColor: { mode: 'live' },
|
|
21
22
|
}),
|
|
22
23
|
})
|
|
23
24
|
|
|
@@ -47,6 +48,7 @@ defineOptions({
|
|
|
47
48
|
fontFamily: block.settings.fontFamily ?? emailEditorStore.resolvedSettings.fontFamily,
|
|
48
49
|
fontSize: `${block.settings.fontSize}px`,
|
|
49
50
|
color: block.settings.textColor ?? emailEditorStore.resolvedSettings.textColor,
|
|
51
|
+
'--link-color': block.settings.linkColor ?? emailEditorStore.resolvedSettings.linkColor,
|
|
50
52
|
}"
|
|
51
53
|
>
|
|
52
54
|
<EditorContent :editor="editor" class="pointer-events-none" />
|
|
@@ -30,6 +30,19 @@ const content = computed({
|
|
|
30
30
|
},
|
|
31
31
|
})
|
|
32
32
|
|
|
33
|
+
const resolvedLinkColor = computed(
|
|
34
|
+
() => props.block.settings.linkColor ?? emailEditorStore.resolvedSettings.linkColor,
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
function matchTextColor() {
|
|
38
|
+
emailEditorStore.updateBlock(props.block.id, {
|
|
39
|
+
settings: {
|
|
40
|
+
...props.block.settings,
|
|
41
|
+
linkColor: props.block.settings.textColor ?? emailEditorStore.resolvedSettings.textColor,
|
|
42
|
+
},
|
|
43
|
+
})
|
|
44
|
+
}
|
|
45
|
+
|
|
33
46
|
const typeOptions = HEADING_TAGS.slice(0, 3).map((heading) => ({
|
|
34
47
|
value: heading,
|
|
35
48
|
label: t(`editor.email.blocks.text_types.${heading}`),
|
|
@@ -51,6 +64,7 @@ function resetColors() {
|
|
|
51
64
|
settings: {
|
|
52
65
|
...props.block.settings,
|
|
53
66
|
textColor: DEFAULT_HEADING_SETTINGS.textColor,
|
|
67
|
+
linkColor: DEFAULT_HEADING_SETTINGS.linkColor,
|
|
54
68
|
backgroundColor: DEFAULT_HEADING_SETTINGS.backgroundColor,
|
|
55
69
|
},
|
|
56
70
|
})
|
|
@@ -83,6 +97,7 @@ defineOptions({
|
|
|
83
97
|
underline
|
|
84
98
|
alignment
|
|
85
99
|
link
|
|
100
|
+
:link-color="resolvedLinkColor"
|
|
86
101
|
emoji
|
|
87
102
|
improve
|
|
88
103
|
generate
|
|
@@ -146,6 +161,25 @@ defineOptions({
|
|
|
146
161
|
:default-value="emailEditorStore.resolvedSettings.textColor"
|
|
147
162
|
/>
|
|
148
163
|
|
|
164
|
+
<!-- Link Color -->
|
|
165
|
+
<ColorInput
|
|
166
|
+
v-model="block.settings.linkColor"
|
|
167
|
+
:label="$t('editor.email.blocks.heading.settings.link')"
|
|
168
|
+
:default-value="emailEditorStore.resolvedSettings.linkColor"
|
|
169
|
+
:data-testid="headingSettingsTestIds.linkColorInput"
|
|
170
|
+
>
|
|
171
|
+
<template #trailing>
|
|
172
|
+
<UButton
|
|
173
|
+
size="xs"
|
|
174
|
+
color="neutral"
|
|
175
|
+
variant="ghost"
|
|
176
|
+
:label="$t('editor.email.blocks.heading.settings.match_text_color')"
|
|
177
|
+
:data-testid="headingSettingsTestIds.matchTextColorButton"
|
|
178
|
+
@click.stop="matchTextColor"
|
|
179
|
+
/>
|
|
180
|
+
</template>
|
|
181
|
+
</ColorInput>
|
|
182
|
+
|
|
149
183
|
<!-- Background Color -->
|
|
150
184
|
<ColorInput
|
|
151
185
|
v-model="block.settings.backgroundColor"
|
|
@@ -18,6 +18,7 @@ const editor = useEditor({
|
|
|
18
18
|
extensions: getTipTapExtensions({
|
|
19
19
|
preset: 'email',
|
|
20
20
|
dynamicValues: true,
|
|
21
|
+
linkColor: { mode: 'live' },
|
|
21
22
|
}),
|
|
22
23
|
})
|
|
23
24
|
|
|
@@ -47,6 +48,7 @@ defineOptions({
|
|
|
47
48
|
fontFamily: block.settings.fontFamily ?? emailEditorStore.resolvedSettings.fontFamily,
|
|
48
49
|
fontSize: `${block.settings.fontSize}px`,
|
|
49
50
|
color: block.settings.textColor ?? emailEditorStore.resolvedSettings.textColor,
|
|
51
|
+
'--link-color': block.settings.linkColor ?? emailEditorStore.resolvedSettings.linkColor,
|
|
50
52
|
}"
|
|
51
53
|
>
|
|
52
54
|
<EditorContent :editor="editor" class="pointer-events-none" />
|
|
@@ -30,6 +30,19 @@ const content = computed({
|
|
|
30
30
|
},
|
|
31
31
|
})
|
|
32
32
|
|
|
33
|
+
const resolvedLinkColor = computed(
|
|
34
|
+
() => props.block.settings.linkColor ?? emailEditorStore.resolvedSettings.linkColor,
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
function matchTextColor() {
|
|
38
|
+
emailEditorStore.updateBlock(props.block.id, {
|
|
39
|
+
settings: {
|
|
40
|
+
...props.block.settings,
|
|
41
|
+
linkColor: props.block.settings.textColor ?? emailEditorStore.resolvedSettings.textColor,
|
|
42
|
+
},
|
|
43
|
+
})
|
|
44
|
+
}
|
|
45
|
+
|
|
33
46
|
const typeOptions = TEXT_TAGS.map((tag) => ({
|
|
34
47
|
value: tag,
|
|
35
48
|
label: t(`editor.email.blocks.text_types.${tag}`),
|
|
@@ -51,6 +64,7 @@ function resetColors() {
|
|
|
51
64
|
settings: {
|
|
52
65
|
...props.block.settings,
|
|
53
66
|
textColor: DEFAULT_PARAGRAPH_SETTINGS.textColor,
|
|
67
|
+
linkColor: DEFAULT_PARAGRAPH_SETTINGS.linkColor,
|
|
54
68
|
backgroundColor: DEFAULT_PARAGRAPH_SETTINGS.backgroundColor,
|
|
55
69
|
},
|
|
56
70
|
})
|
|
@@ -85,6 +99,7 @@ defineOptions({
|
|
|
85
99
|
horizontal-rule
|
|
86
100
|
alignment
|
|
87
101
|
link
|
|
102
|
+
:link-color="resolvedLinkColor"
|
|
88
103
|
emoji
|
|
89
104
|
improve
|
|
90
105
|
generate
|
|
@@ -147,6 +162,25 @@ defineOptions({
|
|
|
147
162
|
:default-value="emailEditorStore.resolvedSettings.textColor"
|
|
148
163
|
/>
|
|
149
164
|
|
|
165
|
+
<!-- Link Color -->
|
|
166
|
+
<ColorInput
|
|
167
|
+
v-model="block.settings.linkColor"
|
|
168
|
+
:label="$t('editor.email.blocks.heading.settings.link')"
|
|
169
|
+
:default-value="emailEditorStore.resolvedSettings.linkColor"
|
|
170
|
+
:data-testid="paragraphSettingsTestIds.linkColorInput"
|
|
171
|
+
>
|
|
172
|
+
<template #trailing>
|
|
173
|
+
<UButton
|
|
174
|
+
size="xs"
|
|
175
|
+
color="neutral"
|
|
176
|
+
variant="ghost"
|
|
177
|
+
:label="$t('editor.email.blocks.heading.settings.match_text_color')"
|
|
178
|
+
:data-testid="paragraphSettingsTestIds.matchTextColorButton"
|
|
179
|
+
@click.stop="matchTextColor"
|
|
180
|
+
/>
|
|
181
|
+
</template>
|
|
182
|
+
</ColorInput>
|
|
183
|
+
|
|
150
184
|
<!-- Background Color -->
|
|
151
185
|
<ColorInput
|
|
152
186
|
v-model="block.settings.backgroundColor"
|
|
@@ -17,6 +17,7 @@ const editor = useEditor({
|
|
|
17
17
|
extensions: getTipTapExtensions({
|
|
18
18
|
preset: 'email',
|
|
19
19
|
dynamicValues: true,
|
|
20
|
+
linkColor: { mode: 'live' },
|
|
20
21
|
}),
|
|
21
22
|
})
|
|
22
23
|
|
|
@@ -45,6 +46,7 @@ defineOptions({
|
|
|
45
46
|
fontFamily: block.settings.fontFamily ?? emailEditorStore.resolvedSettings.fontFamily,
|
|
46
47
|
fontSize: `${block.settings.fontSize}px`,
|
|
47
48
|
color: block.settings.textColor ?? emailEditorStore.resolvedSettings.textColor,
|
|
49
|
+
'--link-color': block.settings.linkColor ?? emailEditorStore.resolvedSettings.linkColor,
|
|
48
50
|
textAlign: block.settings.alignment,
|
|
49
51
|
}"
|
|
50
52
|
>
|
|
@@ -24,6 +24,19 @@ const content = computed({
|
|
|
24
24
|
},
|
|
25
25
|
})
|
|
26
26
|
|
|
27
|
+
const resolvedLinkColor = computed(
|
|
28
|
+
() => props.block.settings.linkColor ?? emailEditorStore.resolvedSettings.linkColor,
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
function matchTextColor() {
|
|
32
|
+
emailEditorStore.updateBlock(props.block.id, {
|
|
33
|
+
settings: {
|
|
34
|
+
...props.block.settings,
|
|
35
|
+
linkColor: props.block.settings.textColor ?? emailEditorStore.resolvedSettings.textColor,
|
|
36
|
+
},
|
|
37
|
+
})
|
|
38
|
+
}
|
|
39
|
+
|
|
27
40
|
function resetTextStyle() {
|
|
28
41
|
emailEditorStore.updateBlock(props.block.id, {
|
|
29
42
|
settings: {
|
|
@@ -39,6 +52,7 @@ function resetColors() {
|
|
|
39
52
|
settings: {
|
|
40
53
|
...props.block.settings,
|
|
41
54
|
textColor: DEFAULT_UNSUBSCRIBE_LINK_SETTINGS.textColor,
|
|
55
|
+
linkColor: DEFAULT_UNSUBSCRIBE_LINK_SETTINGS.linkColor,
|
|
42
56
|
backgroundColor: DEFAULT_UNSUBSCRIBE_LINK_SETTINGS.backgroundColor,
|
|
43
57
|
},
|
|
44
58
|
})
|
|
@@ -63,6 +77,7 @@ defineOptions({
|
|
|
63
77
|
italic
|
|
64
78
|
underline
|
|
65
79
|
link
|
|
80
|
+
:link-color="resolvedLinkColor"
|
|
66
81
|
dynamic-values
|
|
67
82
|
:data-testid="unsubscribeLinkSettingsTestIds.contentEditor"
|
|
68
83
|
/>
|
|
@@ -113,6 +128,24 @@ defineOptions({
|
|
|
113
128
|
:data-testid="unsubscribeLinkSettingsTestIds.textColorInput"
|
|
114
129
|
/>
|
|
115
130
|
|
|
131
|
+
<ColorInput
|
|
132
|
+
v-model="block.settings.linkColor"
|
|
133
|
+
:label="$t('editor.email.blocks.heading.settings.link')"
|
|
134
|
+
:default-value="emailEditorStore.resolvedSettings.linkColor"
|
|
135
|
+
:data-testid="unsubscribeLinkSettingsTestIds.linkColorInput"
|
|
136
|
+
>
|
|
137
|
+
<template #trailing>
|
|
138
|
+
<UButton
|
|
139
|
+
size="xs"
|
|
140
|
+
color="neutral"
|
|
141
|
+
variant="ghost"
|
|
142
|
+
:label="$t('editor.email.blocks.heading.settings.match_text_color')"
|
|
143
|
+
:data-testid="unsubscribeLinkSettingsTestIds.matchTextColorButton"
|
|
144
|
+
@click.stop="matchTextColor"
|
|
145
|
+
/>
|
|
146
|
+
</template>
|
|
147
|
+
</ColorInput>
|
|
148
|
+
|
|
116
149
|
<ColorInput
|
|
117
150
|
v-model="block.settings.backgroundColor"
|
|
118
151
|
:label="$t('editor.email.blocks.heading.settings.backgroundBlock')"
|
|
@@ -35,6 +35,31 @@ export const useMetaSubmissionStore = () => {
|
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
// Submit a single message (one language) for Meta review. Synchronous:
|
|
39
|
+
// the endpoint submits inline and flips the message to `pending`, so there
|
|
40
|
+
// is no job to poll — unlike the group flow.
|
|
41
|
+
const submitMessageToMeta = async (messageId: string) => {
|
|
42
|
+
if (!isConfigured.value) {
|
|
43
|
+
throw new Error('Meta configuration not available')
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
try {
|
|
47
|
+
const response = await metaApi.submitMessage(messageId)
|
|
48
|
+
toast.add({
|
|
49
|
+
color: 'success',
|
|
50
|
+
title: t('meta_submission.message_success'),
|
|
51
|
+
})
|
|
52
|
+
return response
|
|
53
|
+
} catch (error) {
|
|
54
|
+
console.error('Failed to submit message to Meta:', error)
|
|
55
|
+
toast.add({
|
|
56
|
+
color: 'error',
|
|
57
|
+
title: t('meta_submission.message_error'),
|
|
58
|
+
})
|
|
59
|
+
throw error
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
38
63
|
const startBackgroundPolling = (jobId: string, messageGroupId: string) => {
|
|
39
64
|
// Add job to active jobs
|
|
40
65
|
activeJobs.value.set(jobId, {
|
|
@@ -110,6 +135,7 @@ export const useMetaSubmissionStore = () => {
|
|
|
110
135
|
hasActiveJobs,
|
|
111
136
|
isConfigured,
|
|
112
137
|
submitToMeta,
|
|
138
|
+
submitMessageToMeta,
|
|
113
139
|
startBackgroundPolling,
|
|
114
140
|
stopPolling,
|
|
115
141
|
}
|
package/app/types/tracking.ts
CHANGED
|
@@ -105,6 +105,7 @@ export interface TrackingEventMap {
|
|
|
105
105
|
// === Whatsapp_edit ===
|
|
106
106
|
'wa_edit.save_as_new': WaDraftProperties
|
|
107
107
|
'wa_edit.request_approval': WaDraftProperties
|
|
108
|
+
'wa_edit.request_review_language': WaLanguageProperties
|
|
108
109
|
'wa_edit.add_language': WaLanguageProperties
|
|
109
110
|
'wa_edit.remove_language': WaLanguageProperties
|
|
110
111
|
'wa_edit.auto_translate': WaLanguageProperties
|
|
@@ -122,6 +122,7 @@ export const languageListTestIds = {
|
|
|
122
122
|
commandPalette: 'language-list-command-palette',
|
|
123
123
|
languageItem: 'language-list-item',
|
|
124
124
|
deleteButton: 'language-list-delete-button',
|
|
125
|
+
requestReviewButton: 'language-list-request-review-button',
|
|
125
126
|
} as const
|
|
126
127
|
|
|
127
128
|
export const loadingOverlayTestIds = {
|
|
@@ -614,6 +615,8 @@ export const footerSettingsTestIds = {
|
|
|
614
615
|
container: 'footer-settings-container',
|
|
615
616
|
fontSizeField: 'footer-settings-font-size-field',
|
|
616
617
|
fontSizeInput: 'footer-settings-font-size-input',
|
|
618
|
+
linkColorInput: 'footer-settings-link-color-input',
|
|
619
|
+
matchTextColorButton: 'footer-settings-match-text-color-button',
|
|
617
620
|
} as const
|
|
618
621
|
|
|
619
622
|
export const gridBlockTestIds = {
|
|
@@ -652,6 +655,8 @@ export const headingSettingsTestIds = {
|
|
|
652
655
|
tagSelect: 'heading-settings-tag-select',
|
|
653
656
|
fontSizeField: 'heading-settings-font-size-field',
|
|
654
657
|
fontSizeInput: 'heading-settings-font-size-input',
|
|
658
|
+
linkColorInput: 'heading-settings-link-color-input',
|
|
659
|
+
matchTextColorButton: 'heading-settings-match-text-color-button',
|
|
655
660
|
} as const
|
|
656
661
|
|
|
657
662
|
export const htmlBlockTestIds = {
|
|
@@ -690,6 +695,8 @@ export const paragraphSettingsTestIds = {
|
|
|
690
695
|
tagSelect: 'paragraph-settings-tag-select',
|
|
691
696
|
fontSizeField: 'paragraph-settings-font-size-field',
|
|
692
697
|
fontSizeInput: 'paragraph-settings-font-size-input',
|
|
698
|
+
linkColorInput: 'paragraph-settings-link-color-input',
|
|
699
|
+
matchTextColorButton: 'paragraph-settings-match-text-color-button',
|
|
693
700
|
} as const
|
|
694
701
|
|
|
695
702
|
export const socialsBlockTestIds = {
|
|
@@ -731,6 +738,8 @@ export const unsubscribeLinkSettingsTestIds = {
|
|
|
731
738
|
fontSizeInput: 'unsubscribe-link-settings-font-size-input',
|
|
732
739
|
textColorInput: 'unsubscribe-link-settings-text-color-input',
|
|
733
740
|
backgroundColorInput: 'unsubscribe-link-settings-background-color-input',
|
|
741
|
+
linkColorInput: 'unsubscribe-link-settings-link-color-input',
|
|
742
|
+
matchTextColorButton: 'unsubscribe-link-settings-match-text-color-button',
|
|
734
743
|
} as const
|
|
735
744
|
|
|
736
745
|
export const previewByIdTestIds = {
|
package/i18n/locales/de.ts
CHANGED
|
@@ -101,6 +101,12 @@ export default {
|
|
|
101
101
|
success: '„{name}“ wurde veröffentlicht.',
|
|
102
102
|
title: 'Nachricht veröffentlichen',
|
|
103
103
|
},
|
|
104
|
+
request_review: {
|
|
105
|
+
confirm: 'Überprüfung anfordern',
|
|
106
|
+
message:
|
|
107
|
+
'Die {language}-Übersetzung zur Überprüfung einreichen? Sie können sie nicht bearbeiten, solange sie auf Genehmigung wartet.',
|
|
108
|
+
title: 'Überprüfung anfordern',
|
|
109
|
+
},
|
|
104
110
|
unpublish_message_group: {
|
|
105
111
|
message:
|
|
106
112
|
'Veröffentlichung von „{name}“ aufheben? Es ist dann nicht mehr für Kundinnen und Kunden sichtbar.',
|
|
@@ -260,6 +266,8 @@ export default {
|
|
|
260
266
|
color: 'Farbe',
|
|
261
267
|
content: 'Inhalt',
|
|
262
268
|
font: 'Schriftart',
|
|
269
|
+
link: 'Link',
|
|
270
|
+
match_text_color: 'An Textfarbe anpassen',
|
|
263
271
|
size: 'Größe',
|
|
264
272
|
text: 'Text',
|
|
265
273
|
textStyle: 'Textstil',
|
|
@@ -613,6 +621,7 @@ export default {
|
|
|
613
621
|
change: 'Änderung',
|
|
614
622
|
changes: 'Änderungen',
|
|
615
623
|
changes_count: '{count} Änderungen',
|
|
624
|
+
request_review: 'Überprüfung anfordern',
|
|
616
625
|
translated_percentage: '{percentage}% übersetzt',
|
|
617
626
|
unsaved_changes: 'Diese Übersetzung hat ungespeicherte Änderungen',
|
|
618
627
|
},
|
|
@@ -625,6 +634,8 @@ export default {
|
|
|
625
634
|
meta_submission: {
|
|
626
635
|
error: 'Meta-Übermittlung mit Fehlern abgeschlossen',
|
|
627
636
|
failed_count: 'Fehlgeschlagene Nachrichten: {count}',
|
|
637
|
+
message_error: 'Übersetzung konnte nicht zur Überprüfung eingereicht werden',
|
|
638
|
+
message_success: 'Übersetzung zur Überprüfung eingereicht',
|
|
628
639
|
success: 'Nachrichten an Meta übermittelt',
|
|
629
640
|
},
|
|
630
641
|
modals: {
|
|
@@ -684,6 +695,7 @@ export default {
|
|
|
684
695
|
default_font: 'Standardschriftart',
|
|
685
696
|
email_bg_color: 'Hintergrund',
|
|
686
697
|
email_content_bg_color: 'Inhalt-Hintergrund',
|
|
698
|
+
email_link_color: 'Link-Farbe',
|
|
687
699
|
email_text_color: 'Text',
|
|
688
700
|
extracting_colors: 'Farben werden aus dem Logo extrahiert...',
|
|
689
701
|
logo: 'Logo',
|
package/i18n/locales/en.ts
CHANGED
|
@@ -97,6 +97,12 @@ export default {
|
|
|
97
97
|
success: '"{name}" has been published.',
|
|
98
98
|
title: 'Publish message',
|
|
99
99
|
},
|
|
100
|
+
request_review: {
|
|
101
|
+
confirm: 'Request review',
|
|
102
|
+
message:
|
|
103
|
+
"Submit the {language} translation for review? You won't be able to edit it while it's pending approval.",
|
|
104
|
+
title: 'Request review',
|
|
105
|
+
},
|
|
100
106
|
unpublish_message_group: {
|
|
101
107
|
message: 'Unpublish "{name}"? It will no longer be visible to clients.',
|
|
102
108
|
success: '"{name}" has been unpublished.',
|
|
@@ -254,6 +260,8 @@ export default {
|
|
|
254
260
|
color: 'Color',
|
|
255
261
|
content: 'Content',
|
|
256
262
|
font: 'Font',
|
|
263
|
+
link: 'Link',
|
|
264
|
+
match_text_color: 'Match text color',
|
|
257
265
|
size: 'Size',
|
|
258
266
|
text: 'Text',
|
|
259
267
|
textStyle: 'Text style',
|
|
@@ -603,6 +611,7 @@ export default {
|
|
|
603
611
|
change: 'change',
|
|
604
612
|
changes: 'changes',
|
|
605
613
|
changes_count: '{count} changes',
|
|
614
|
+
request_review: 'Request review',
|
|
606
615
|
translated_percentage: '{percentage}% translated',
|
|
607
616
|
unsaved_changes: 'This translation has unsaved changes',
|
|
608
617
|
},
|
|
@@ -615,6 +624,8 @@ export default {
|
|
|
615
624
|
meta_submission: {
|
|
616
625
|
error: 'Meta submission completed with errors',
|
|
617
626
|
failed_count: 'Failed messages: {count}',
|
|
627
|
+
message_error: 'Failed to submit translation for review',
|
|
628
|
+
message_success: 'Translation submitted for review',
|
|
618
629
|
success: 'Messages submitted to Meta',
|
|
619
630
|
},
|
|
620
631
|
modals: {
|
|
@@ -673,6 +684,7 @@ export default {
|
|
|
673
684
|
default_font: 'Default font',
|
|
674
685
|
email_bg_color: 'Background',
|
|
675
686
|
email_content_bg_color: 'Content background',
|
|
687
|
+
email_link_color: 'Link color',
|
|
676
688
|
email_text_color: 'Text',
|
|
677
689
|
extracting_colors: 'Extracting colors from logo...',
|
|
678
690
|
logo: 'Logo',
|
package/i18n/locales/es.ts
CHANGED
|
@@ -98,6 +98,12 @@ export default {
|
|
|
98
98
|
success: '"{name}" se ha publicado.',
|
|
99
99
|
title: 'Publicar mensaje',
|
|
100
100
|
},
|
|
101
|
+
request_review: {
|
|
102
|
+
confirm: 'Solicitar revisión',
|
|
103
|
+
message:
|
|
104
|
+
'¿Enviar la traducción en {language} para revisión? No podrá editarla mientras esté pendiente de aprobación.',
|
|
105
|
+
title: 'Solicitar revisión',
|
|
106
|
+
},
|
|
101
107
|
unpublish_message_group: {
|
|
102
108
|
message: '¿Despublicar "{name}"? Ya no será visible para los clientes.',
|
|
103
109
|
success: '"{name}" se ha despublicado.',
|
|
@@ -255,6 +261,8 @@ export default {
|
|
|
255
261
|
color: 'Color',
|
|
256
262
|
content: 'Contenido',
|
|
257
263
|
font: 'Fuente',
|
|
264
|
+
link: 'Enlace',
|
|
265
|
+
match_text_color: 'Igualar al color del texto',
|
|
258
266
|
size: 'Tamaño',
|
|
259
267
|
text: 'Texto',
|
|
260
268
|
textStyle: 'Estilo del texto',
|
|
@@ -611,6 +619,7 @@ export default {
|
|
|
611
619
|
change: 'cambio',
|
|
612
620
|
changes: 'cambios',
|
|
613
621
|
changes_count: '{count} cambios',
|
|
622
|
+
request_review: 'Solicitar revisión',
|
|
614
623
|
translated_percentage: '{percentage}% traducido',
|
|
615
624
|
unsaved_changes: 'Esta traducción tiene cambios sin guardar',
|
|
616
625
|
},
|
|
@@ -623,6 +632,8 @@ export default {
|
|
|
623
632
|
meta_submission: {
|
|
624
633
|
error: 'Envío a Meta completado con errores',
|
|
625
634
|
failed_count: 'Mensajes fallidos: {count}',
|
|
635
|
+
message_error: 'No se pudo enviar la traducción para revisión',
|
|
636
|
+
message_success: 'Traducción enviada para revisión',
|
|
626
637
|
success: 'Mensajes enviados a Meta',
|
|
627
638
|
},
|
|
628
639
|
modals: {
|
|
@@ -682,6 +693,7 @@ export default {
|
|
|
682
693
|
default_font: 'Fuente predeterminada',
|
|
683
694
|
email_bg_color: 'Fondo',
|
|
684
695
|
email_content_bg_color: 'Fondo contenido',
|
|
696
|
+
email_link_color: 'Color de enlace',
|
|
685
697
|
email_text_color: 'Texto',
|
|
686
698
|
extracting_colors: 'Extrayendo colores del logo...',
|
|
687
699
|
logo: 'Logo',
|
package/i18n/locales/fr.ts
CHANGED
|
@@ -98,6 +98,12 @@ export default {
|
|
|
98
98
|
success: '« {name} » a été publié.',
|
|
99
99
|
title: 'Publier le message',
|
|
100
100
|
},
|
|
101
|
+
request_review: {
|
|
102
|
+
confirm: 'Demander une révision',
|
|
103
|
+
message:
|
|
104
|
+
'Envoyer la traduction {language} pour révision ? Vous ne pourrez pas la modifier tant qu’elle est en attente d’approbation.',
|
|
105
|
+
title: 'Demander une révision',
|
|
106
|
+
},
|
|
101
107
|
unpublish_message_group: {
|
|
102
108
|
message: 'Dépublier « {name} » ? Il ne sera plus visible aux clients.',
|
|
103
109
|
success: '« {name} » a été dépublié.',
|
|
@@ -256,6 +262,8 @@ export default {
|
|
|
256
262
|
color: 'Couleur',
|
|
257
263
|
content: 'Contenu',
|
|
258
264
|
font: 'Police',
|
|
265
|
+
link: 'Lien',
|
|
266
|
+
match_text_color: 'Assortir à la couleur du texte',
|
|
259
267
|
size: 'Taille',
|
|
260
268
|
text: 'Texte',
|
|
261
269
|
textStyle: 'Style de texte',
|
|
@@ -615,6 +623,7 @@ export default {
|
|
|
615
623
|
change: 'modification',
|
|
616
624
|
changes: 'modifications',
|
|
617
625
|
changes_count: '{count} modifications',
|
|
626
|
+
request_review: 'Demander une révision',
|
|
618
627
|
translated_percentage: '{percentage}% traduit',
|
|
619
628
|
unsaved_changes: 'Cette traduction contient des modifications non enregistrées',
|
|
620
629
|
},
|
|
@@ -627,6 +636,8 @@ export default {
|
|
|
627
636
|
meta_submission: {
|
|
628
637
|
error: 'Soumission à Meta terminée avec des erreurs',
|
|
629
638
|
failed_count: 'Messages en échec : {count}',
|
|
639
|
+
message_error: 'Échec de l’envoi de la traduction pour révision',
|
|
640
|
+
message_success: 'Traduction envoyée pour révision',
|
|
630
641
|
success: 'Messages soumis à Meta',
|
|
631
642
|
},
|
|
632
643
|
modals: {
|
|
@@ -686,6 +697,7 @@ export default {
|
|
|
686
697
|
default_font: 'Police par défaut',
|
|
687
698
|
email_bg_color: 'Fond',
|
|
688
699
|
email_content_bg_color: 'Fond contenu',
|
|
700
|
+
email_link_color: 'Couleur du lien',
|
|
689
701
|
email_text_color: 'Texte',
|
|
690
702
|
extracting_colors: 'Extraction des couleurs du logo...',
|
|
691
703
|
logo: 'Logo',
|
package/i18n/locales/it.ts
CHANGED
|
@@ -97,6 +97,12 @@ export default {
|
|
|
97
97
|
success: '"{name}" è stato pubblicato.',
|
|
98
98
|
title: 'Pubblica messaggio',
|
|
99
99
|
},
|
|
100
|
+
request_review: {
|
|
101
|
+
confirm: 'Richiedi revisione',
|
|
102
|
+
message:
|
|
103
|
+
'Inviare per la revisione la traduzione in {language}? Non potrai modificarla finché è in attesa di approvazione.',
|
|
104
|
+
title: 'Richiedi revisione',
|
|
105
|
+
},
|
|
100
106
|
unpublish_message_group: {
|
|
101
107
|
message: 'Annullare la pubblicazione di "{name}"? Non sarà più visibile ai clienti.',
|
|
102
108
|
success: 'La pubblicazione di "{name}" è stata annullata.',
|
|
@@ -255,6 +261,8 @@ export default {
|
|
|
255
261
|
color: 'Colore',
|
|
256
262
|
content: 'Contenuto',
|
|
257
263
|
font: 'Font',
|
|
264
|
+
link: 'Link',
|
|
265
|
+
match_text_color: 'Abbina al colore del testo',
|
|
258
266
|
size: 'Dimensione',
|
|
259
267
|
text: 'Testo',
|
|
260
268
|
textStyle: 'Stile testo',
|
|
@@ -608,6 +616,7 @@ export default {
|
|
|
608
616
|
change: 'modifica',
|
|
609
617
|
changes: 'modifiche',
|
|
610
618
|
changes_count: '{count} modifiche',
|
|
619
|
+
request_review: 'Richiedi revisione',
|
|
611
620
|
translated_percentage: '{percentage}% tradotto',
|
|
612
621
|
unsaved_changes: 'Questa traduzione ha modifiche non salvate',
|
|
613
622
|
},
|
|
@@ -620,6 +629,8 @@ export default {
|
|
|
620
629
|
meta_submission: {
|
|
621
630
|
error: 'Invio a Meta completato con errori',
|
|
622
631
|
failed_count: 'Messaggi non riusciti: {count}',
|
|
632
|
+
message_error: 'Impossibile inviare la traduzione per la revisione',
|
|
633
|
+
message_success: 'Traduzione inviata per la revisione',
|
|
623
634
|
success: 'Messaggi inviati a Meta',
|
|
624
635
|
},
|
|
625
636
|
modals: {
|
|
@@ -679,6 +690,7 @@ export default {
|
|
|
679
690
|
default_font: 'Font predefinito',
|
|
680
691
|
email_bg_color: 'Sfondo',
|
|
681
692
|
email_content_bg_color: 'Sfondo contenuto',
|
|
693
|
+
email_link_color: 'Colore link',
|
|
682
694
|
email_text_color: 'Testo',
|
|
683
695
|
extracting_colors: 'Estrazione dei colori dal logo...',
|
|
684
696
|
logo: 'Logo',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dev.smartpricing/message-composer-layer",
|
|
3
|
-
"version": "4.2.11-ux.
|
|
3
|
+
"version": "4.2.11-ux.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./nuxt.config.ts",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"vue-router": "^5.0.7",
|
|
37
37
|
"vue3-emoji-picker": "^1.1.8",
|
|
38
38
|
"zod": "^4.4.3",
|
|
39
|
-
"@dev.smartpricing/message-composer-utils": "4.2.11-ux.
|
|
39
|
+
"@dev.smartpricing/message-composer-utils": "4.2.11-ux.1"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@nuxt/eslint": "^1.15.2",
|