@dev.smartpricing/message-composer-layer 4.0.2-templates.1 → 4.0.2-tepmlates.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/app/api/templates.ts +0 -7
- package/app/components/Common/NewMessageModal.vue +6 -4
- package/app/components/Composer/MessageLibrary.vue +1 -1
- package/app/pages/templates/email/create.vue +13 -1
- package/app/pages/templates/index.vue +4 -22
- package/app/pages/templates/whatsapp/create.vue +13 -1
- package/app/queries/templates.ts +0 -13
- package/i18n/locales/de.ts +0 -1
- package/i18n/locales/en.ts +0 -12
- package/i18n/locales/es.ts +0 -1
- package/i18n/locales/fr.ts +0 -1
- package/i18n/locales/it.ts +0 -1
- package/package.json +2 -2
- package/app/components/TemplateList/PromoteModal.vue +0 -69
package/app/api/templates.ts
CHANGED
|
@@ -4,7 +4,6 @@ import type {
|
|
|
4
4
|
TemplateWithMessageSummary,
|
|
5
5
|
CreateTemplatePayload,
|
|
6
6
|
UpdateTemplatePayload,
|
|
7
|
-
PromoteTemplatePayload,
|
|
8
7
|
} from '@dev.smartpricing/message-composer-utils/types'
|
|
9
8
|
import { apiClient } from './client'
|
|
10
9
|
|
|
@@ -48,12 +47,6 @@ export const templatesApi = {
|
|
|
48
47
|
unpublish: (id: string) =>
|
|
49
48
|
apiClient<TemplateFromDb>(`/templates/${id}/unpublish`, { method: 'PUT' }),
|
|
50
49
|
|
|
51
|
-
promote: (id: string, data: PromoteTemplatePayload) =>
|
|
52
|
-
apiClient<TemplateFromDb>(`/templates/${id}/promote`, {
|
|
53
|
-
method: 'POST',
|
|
54
|
-
body: data,
|
|
55
|
-
}),
|
|
56
|
-
|
|
57
50
|
saveFromMessageGroup: (messageGroupId: string, name?: string) =>
|
|
58
51
|
apiClient<TemplateFromDb>(`/message-groups/${messageGroupId}/save-as-template`, {
|
|
59
52
|
method: 'POST',
|
|
@@ -14,6 +14,7 @@ import { templatesApi } from '~/api/templates'
|
|
|
14
14
|
|
|
15
15
|
const isOpen = defineModel<boolean>('open', { required: true })
|
|
16
16
|
|
|
17
|
+
const router = useRouter()
|
|
17
18
|
const { t, locale } = useI18n()
|
|
18
19
|
const { mainLanguage } = storeToRefs(useAppContextStore())
|
|
19
20
|
const { allowedRenderTypes, defaultRenderType } = useChannels()
|
|
@@ -134,10 +135,11 @@ function selectTemplate(tmpl: TemplateWithMessageSummary) {
|
|
|
134
135
|
function handleCreate() {
|
|
135
136
|
isOpen.value = false
|
|
136
137
|
const channel = renderTypeToChannel(renderType.value)
|
|
137
|
-
const
|
|
138
|
-
if (selectedId.value)
|
|
139
|
-
if (brand.value)
|
|
140
|
-
|
|
138
|
+
const params = new URLSearchParams()
|
|
139
|
+
if (selectedId.value) params.set('from_template', selectedId.value)
|
|
140
|
+
if (brand.value) params.set('brand_id', brand.value.id)
|
|
141
|
+
const query = params.size ? `?${params.toString()}` : ''
|
|
142
|
+
router.push(`/compose/${channel}/create${query}`)
|
|
141
143
|
}
|
|
142
144
|
</script>
|
|
143
145
|
|
|
@@ -164,7 +164,7 @@ function navigate(row: MessageGroupWithMessageSummary) {
|
|
|
164
164
|
trackEvent('message_edit', getMessageTrackingProps(row))
|
|
165
165
|
emit('edit', row)
|
|
166
166
|
const type = row.messages[0]?.render_type === 'email_v1' ? 'email' : 'whatsapp'
|
|
167
|
-
|
|
167
|
+
router.push({ name: `${type}-message-edit`, params: { id: row.id } })
|
|
168
168
|
}
|
|
169
169
|
|
|
170
170
|
defineExpose({ execute })
|
|
@@ -13,6 +13,9 @@ const toast = useToast()
|
|
|
13
13
|
const { t } = useI18n()
|
|
14
14
|
const { goBackOrFallback } = useGoBack()
|
|
15
15
|
|
|
16
|
+
const appContext = useAppContextStore()
|
|
17
|
+
const isSystem = ref(false)
|
|
18
|
+
|
|
16
19
|
const { mutateAsync: createTemplate } = useCreateTemplateMutation()
|
|
17
20
|
const saving = ref(false)
|
|
18
21
|
|
|
@@ -33,6 +36,7 @@ async function handleSave() {
|
|
|
33
36
|
name: store.name,
|
|
34
37
|
category: store.category,
|
|
35
38
|
messages,
|
|
39
|
+
...(appContext.isAdmin && isSystem.value ? { is_system: true } : {}),
|
|
36
40
|
})
|
|
37
41
|
|
|
38
42
|
toast.add({ title: t('templates.dialogs.save_as_template.success'), color: 'success' })
|
|
@@ -69,6 +73,14 @@ async function handleSave() {
|
|
|
69
73
|
/>
|
|
70
74
|
</template>
|
|
71
75
|
|
|
72
|
-
<ComposerEmailComposer ref="composerRef" mode="create"
|
|
76
|
+
<ComposerEmailComposer ref="composerRef" mode="create">
|
|
77
|
+
<template #actions>
|
|
78
|
+
<UCheckbox
|
|
79
|
+
v-if="appContext.isAdmin"
|
|
80
|
+
v-model="isSystem"
|
|
81
|
+
:label="$t('templates.system_template')"
|
|
82
|
+
/>
|
|
83
|
+
</template>
|
|
84
|
+
</ComposerEmailComposer>
|
|
73
85
|
</LayoutBasePage>
|
|
74
86
|
</template>
|
|
@@ -8,6 +8,7 @@ definePageMeta({
|
|
|
8
8
|
name: 'template-library',
|
|
9
9
|
})
|
|
10
10
|
|
|
11
|
+
const router = useRouter()
|
|
11
12
|
const { t, locale } = useI18n()
|
|
12
13
|
const toast = useToast()
|
|
13
14
|
const { hasWhatsapp, hasEmail, defaultRenderType, isRenderTypeAllowed } = useChannels()
|
|
@@ -38,13 +39,6 @@ const { data: templates, isPending } = useTemplatesQuery(
|
|
|
38
39
|
const { mutateAsync: deleteTemplate } = useDeleteTemplateMutation()
|
|
39
40
|
const { mutateAsync: publishTemplate } = usePublishTemplateMutation()
|
|
40
41
|
const { mutateAsync: unpublishTemplate } = useUnpublishTemplateMutation()
|
|
41
|
-
const promoteTarget = ref<TemplateWithMessageSummary | null>(null)
|
|
42
|
-
const isPromoteModalOpen = computed({
|
|
43
|
-
get: () => promoteTarget.value !== null,
|
|
44
|
-
set: (v) => {
|
|
45
|
-
if (!v) promoteTarget.value = null
|
|
46
|
-
},
|
|
47
|
-
})
|
|
48
42
|
|
|
49
43
|
const tabItems = computed(() => {
|
|
50
44
|
const items = []
|
|
@@ -85,7 +79,7 @@ function channelFromRenderType(rt: RenderType): 'email' | 'whatsapp' {
|
|
|
85
79
|
|
|
86
80
|
function editTemplate(tmpl: TemplateWithMessageSummary) {
|
|
87
81
|
const channel = channelFromRenderType(tmpl.messages[0]?.render_type || renderType.value)
|
|
88
|
-
|
|
82
|
+
router.push(`/templates/${channel}/${tmpl.id}`)
|
|
89
83
|
}
|
|
90
84
|
|
|
91
85
|
async function handleDelete(tmpl: TemplateWithMessageSummary) {
|
|
@@ -111,7 +105,7 @@ async function handleUnpublish(tmpl: TemplateWithMessageSummary) {
|
|
|
111
105
|
|
|
112
106
|
function handleUse(tmpl: TemplateWithMessageSummary) {
|
|
113
107
|
const channel = channelFromRenderType(tmpl.messages[0]?.render_type || renderType.value)
|
|
114
|
-
|
|
108
|
+
router.push(`/compose/${channel}/create?from_template=${tmpl.id}`)
|
|
115
109
|
}
|
|
116
110
|
|
|
117
111
|
function rowActions(tmpl: TemplateWithMessageSummary) {
|
|
@@ -124,16 +118,6 @@ function rowActions(tmpl: TemplateWithMessageSummary) {
|
|
|
124
118
|
]
|
|
125
119
|
|
|
126
120
|
if (appContext.isAdmin) {
|
|
127
|
-
if (tmpl.user_id !== SYSTEM_USER_ID) {
|
|
128
|
-
actions.push({
|
|
129
|
-
label: t('templates.dialogs.promote.title'),
|
|
130
|
-
icon: 'ph:arrow-fat-up',
|
|
131
|
-
onSelect: () => {
|
|
132
|
-
promoteTarget.value = tmpl
|
|
133
|
-
},
|
|
134
|
-
})
|
|
135
|
-
}
|
|
136
|
-
|
|
137
121
|
if (tmpl.visibility === 'internal') {
|
|
138
122
|
actions.push({
|
|
139
123
|
label: t('common.actions.publish'),
|
|
@@ -159,7 +143,7 @@ function rowActions(tmpl: TemplateWithMessageSummary) {
|
|
|
159
143
|
|
|
160
144
|
function createTemplate() {
|
|
161
145
|
const channel = channelFromRenderType(renderType.value)
|
|
162
|
-
|
|
146
|
+
router.push(`/templates/${channel}/create`)
|
|
163
147
|
}
|
|
164
148
|
</script>
|
|
165
149
|
|
|
@@ -257,7 +241,5 @@ function createTemplate() {
|
|
|
257
241
|
</UTable>
|
|
258
242
|
</UCard>
|
|
259
243
|
</div>
|
|
260
|
-
|
|
261
|
-
<TemplateListPromoteModal v-model:open="isPromoteModalOpen" :template="promoteTarget" />
|
|
262
244
|
</LayoutBasePage>
|
|
263
245
|
</template>
|
|
@@ -13,6 +13,9 @@ const toast = useToast()
|
|
|
13
13
|
const { t } = useI18n()
|
|
14
14
|
const { goBackOrFallback } = useGoBack()
|
|
15
15
|
|
|
16
|
+
const appContext = useAppContextStore()
|
|
17
|
+
const isSystem = ref(false)
|
|
18
|
+
|
|
16
19
|
const { mutateAsync: createTemplate } = useCreateTemplateMutation()
|
|
17
20
|
const saving = ref(false)
|
|
18
21
|
|
|
@@ -33,6 +36,7 @@ async function handleSave() {
|
|
|
33
36
|
name: store.name,
|
|
34
37
|
category: store.category,
|
|
35
38
|
messages,
|
|
39
|
+
...(appContext.isAdmin && isSystem.value ? { is_system: true } : {}),
|
|
36
40
|
})
|
|
37
41
|
|
|
38
42
|
toast.add({ title: t('templates.dialogs.save_as_template.success'), color: 'success' })
|
|
@@ -69,6 +73,14 @@ async function handleSave() {
|
|
|
69
73
|
/>
|
|
70
74
|
</template>
|
|
71
75
|
|
|
72
|
-
<ComposerWhatsappComposer ref="composerRef" mode="create"
|
|
76
|
+
<ComposerWhatsappComposer ref="composerRef" mode="create">
|
|
77
|
+
<template #actions>
|
|
78
|
+
<UCheckbox
|
|
79
|
+
v-if="appContext.isAdmin"
|
|
80
|
+
v-model="isSystem"
|
|
81
|
+
:label="$t('templates.system_template')"
|
|
82
|
+
/>
|
|
83
|
+
</template>
|
|
84
|
+
</ComposerWhatsappComposer>
|
|
73
85
|
</LayoutBasePage>
|
|
74
86
|
</template>
|
package/app/queries/templates.ts
CHANGED
|
@@ -4,7 +4,6 @@ import type {
|
|
|
4
4
|
TemplateWithMessageSummary,
|
|
5
5
|
CreateTemplatePayload,
|
|
6
6
|
UpdateTemplatePayload,
|
|
7
|
-
PromoteTemplatePayload,
|
|
8
7
|
} from '@dev.smartpricing/message-composer-utils/types'
|
|
9
8
|
import { templatesApi } from '~/api/templates'
|
|
10
9
|
|
|
@@ -107,18 +106,6 @@ export function useUnpublishTemplateMutation() {
|
|
|
107
106
|
})
|
|
108
107
|
}
|
|
109
108
|
|
|
110
|
-
export function usePromoteTemplateMutation() {
|
|
111
|
-
const queryCache = useQueryCache()
|
|
112
|
-
|
|
113
|
-
return useMutation({
|
|
114
|
-
mutation: ({ id, data }: { id: string; data: PromoteTemplatePayload }) =>
|
|
115
|
-
templatesApi.promote(id, data),
|
|
116
|
-
onSuccess: () => {
|
|
117
|
-
queryCache.invalidateQueries({ key: ['templates'] })
|
|
118
|
-
},
|
|
119
|
-
})
|
|
120
|
-
}
|
|
121
|
-
|
|
122
109
|
export function useSaveAsTemplateMutation() {
|
|
123
110
|
const queryCache = useQueryCache()
|
|
124
111
|
|
package/i18n/locales/de.ts
CHANGED
package/i18n/locales/en.ts
CHANGED
|
@@ -43,7 +43,6 @@ export default {
|
|
|
43
43
|
save: 'Save',
|
|
44
44
|
remove: 'Remove',
|
|
45
45
|
reset_defaults: 'Reset to defaults',
|
|
46
|
-
confirm: 'Confirm',
|
|
47
46
|
},
|
|
48
47
|
internal: 'Internal',
|
|
49
48
|
imageUpload: {
|
|
@@ -861,17 +860,6 @@ These messages must be functional, not promotional.
|
|
|
861
860
|
message: 'Save this message as a reusable template?',
|
|
862
861
|
success: 'Template saved successfully.',
|
|
863
862
|
},
|
|
864
|
-
promote: {
|
|
865
|
-
title: 'Promote to System Template',
|
|
866
|
-
clone_label: 'Clone as System',
|
|
867
|
-
clone_description:
|
|
868
|
-
'Create an independent copy as a system template. The original template stays unchanged.',
|
|
869
|
-
convert_label: 'Convert to System',
|
|
870
|
-
convert_description:
|
|
871
|
-
'This template will become a system template. The original owner will lose ownership. This action cannot be undone.',
|
|
872
|
-
success_clone: '"{name}" cloned as system template.',
|
|
873
|
-
success_convert: '"{name}" promoted to system template.',
|
|
874
|
-
},
|
|
875
863
|
},
|
|
876
864
|
copy_success: 'Message created from template.',
|
|
877
865
|
},
|
package/i18n/locales/es.ts
CHANGED
package/i18n/locales/fr.ts
CHANGED
package/i18n/locales/it.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dev.smartpricing/message-composer-layer",
|
|
3
|
-
"version": "4.0.2-
|
|
3
|
+
"version": "4.0.2-tepmlates.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./nuxt.config.ts",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"vue-router": "^5.0.7",
|
|
39
39
|
"vue3-emoji-picker": "^1.1.8",
|
|
40
40
|
"zod": "^4.4.3",
|
|
41
|
-
"@dev.smartpricing/message-composer-utils": "4.0.3-
|
|
41
|
+
"@dev.smartpricing/message-composer-utils": "4.0.3-tepmlates.0"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"@nuxt/eslint": "^1.15.2",
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
import type { TemplateWithMessageSummary } from '@dev.smartpricing/message-composer-utils/types'
|
|
3
|
-
|
|
4
|
-
const props = defineProps<{
|
|
5
|
-
template: TemplateWithMessageSummary | null
|
|
6
|
-
}>()
|
|
7
|
-
|
|
8
|
-
const emit = defineEmits<{
|
|
9
|
-
confirm: [mode: 'clone' | 'convert']
|
|
10
|
-
}>()
|
|
11
|
-
|
|
12
|
-
const open = defineModel<boolean>('open', { required: true })
|
|
13
|
-
|
|
14
|
-
const { t } = useI18n()
|
|
15
|
-
const { mutateAsync: promoteTemplate, isPending } = usePromoteTemplateMutation()
|
|
16
|
-
const toast = useToast()
|
|
17
|
-
|
|
18
|
-
const mode = ref<'clone' | 'convert'>('clone')
|
|
19
|
-
|
|
20
|
-
const items = computed(() => [
|
|
21
|
-
{
|
|
22
|
-
label: t('templates.dialogs.promote.clone_label'),
|
|
23
|
-
description: t('templates.dialogs.promote.clone_description'),
|
|
24
|
-
value: 'clone' as const,
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
label: t('templates.dialogs.promote.convert_label'),
|
|
28
|
-
description: t('templates.dialogs.promote.convert_description'),
|
|
29
|
-
value: 'convert' as const,
|
|
30
|
-
},
|
|
31
|
-
])
|
|
32
|
-
|
|
33
|
-
async function handleConfirm() {
|
|
34
|
-
if (!props.template) return
|
|
35
|
-
await promoteTemplate({ id: props.template.id, data: { mode: mode.value } })
|
|
36
|
-
const key = mode.value === 'clone' ? 'success_clone' : 'success_convert'
|
|
37
|
-
toast.add({
|
|
38
|
-
title: t(`templates.dialogs.promote.${key}`, { name: props.template.name }),
|
|
39
|
-
color: 'success',
|
|
40
|
-
})
|
|
41
|
-
open.value = false
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
watch(open, (v) => {
|
|
45
|
-
if (v) mode.value = 'clone'
|
|
46
|
-
})
|
|
47
|
-
</script>
|
|
48
|
-
|
|
49
|
-
<template>
|
|
50
|
-
<UModal
|
|
51
|
-
v-model:open="open"
|
|
52
|
-
:title="$t('templates.dialogs.promote.title')"
|
|
53
|
-
:ui="{ footer: 'justify-end' }"
|
|
54
|
-
>
|
|
55
|
-
<template #body>
|
|
56
|
-
<URadioGroup v-model="mode" :items="items" variant="card" color="secondary" />
|
|
57
|
-
</template>
|
|
58
|
-
|
|
59
|
-
<template #footer>
|
|
60
|
-
<UButton variant="outline" :label="$t('common.actions.cancel')" @click="open = false" />
|
|
61
|
-
<UButton
|
|
62
|
-
color="primary"
|
|
63
|
-
:label="$t('common.actions.confirm')"
|
|
64
|
-
:loading="isPending"
|
|
65
|
-
@click="handleConfirm"
|
|
66
|
-
/>
|
|
67
|
-
</template>
|
|
68
|
-
</UModal>
|
|
69
|
-
</template>
|