diff --git a/frontend/components.d.ts b/frontend/components.d.ts index e09a16f1..ed71d6c9 100644 --- a/frontend/components.d.ts +++ b/frontend/components.d.ts @@ -79,6 +79,7 @@ declare module 'vue' { DropdownItem: typeof import('./src/components/DropdownItem.vue')['default'] DuplicateIcon: typeof import('./src/components/Icons/DuplicateIcon.vue')['default'] DurationIcon: typeof import('./src/components/Icons/DurationIcon.vue')['default'] + EditEmailTemplate: typeof import('./src/components/Settings/EmailTemplate/EditEmailTemplate.vue')['default'] EditIcon: typeof import('./src/components/Icons/EditIcon.vue')['default'] EditValueModal: typeof import('./src/components/Modals/EditValueModal.vue')['default'] Email2Icon: typeof import('./src/components/Icons/Email2Icon.vue')['default'] @@ -94,6 +95,7 @@ declare module 'vue' { EmailIcon: typeof import('./src/components/Icons/EmailIcon.vue')['default'] EmailProviderIcon: typeof import('./src/components/Settings/EmailProviderIcon.vue')['default'] EmailTemplateModal: typeof import('./src/components/Modals/EmailTemplateModal.vue')['default'] + EmailTemplatePage: typeof import('./src/components/Settings/EmailTemplate/EmailTemplatePage.vue')['default'] EmailTemplates: typeof import('./src/components/Settings/EmailTemplate/EmailTemplates.vue')['default'] EmailTemplateSelectorModal: typeof import('./src/components/Modals/EmailTemplateSelectorModal.vue')['default'] EmailTemplatesListView: typeof import('./src/components/ListViews/EmailTemplatesListView.vue')['default'] @@ -156,8 +158,10 @@ declare module 'vue' { ListRows: typeof import('./src/components/ListViews/ListRows.vue')['default'] LoadingIndicator: typeof import('./src/components/Icons/LoadingIndicator.vue')['default'] LucideInfo: typeof import('~icons/lucide/info')['default'] + LucideMoreHorizontal: typeof import('~icons/lucide/more-horizontal')['default'] LucidePlus: typeof import('~icons/lucide/plus')['default'] LucideSearch: typeof import('~icons/lucide/search')['default'] + LucideX: typeof import('~icons/lucide/x')['default'] MarkAsDoneIcon: typeof import('./src/components/Icons/MarkAsDoneIcon.vue')['default'] MaximizeIcon: typeof import('./src/components/Icons/MaximizeIcon.vue')['default'] MenuIcon: typeof import('./src/components/Icons/MenuIcon.vue')['default'] @@ -173,6 +177,7 @@ declare module 'vue' { MultiSelectUserInput: typeof import('./src/components/Controls/MultiSelectUserInput.vue')['default'] MuteIcon: typeof import('./src/components/Icons/MuteIcon.vue')['default'] NestedPopover: typeof import('./src/components/NestedPopover.vue')['default'] + NewEmailTemplate: typeof import('./src/components/Settings/EmailTemplate/NewEmailTemplate.vue')['default'] NoteArea: typeof import('./src/components/Activities/NoteArea.vue')['default'] NoteIcon: typeof import('./src/components/Icons/NoteIcon.vue')['default'] NoteModal: typeof import('./src/components/Modals/NoteModal.vue')['default'] diff --git a/frontend/src/components/Settings/EmailTemplate/EditEmailTemplate.vue b/frontend/src/components/Settings/EmailTemplate/EditEmailTemplate.vue new file mode 100644 index 00000000..b9f1a8b2 --- /dev/null +++ b/frontend/src/components/Settings/EmailTemplate/EditEmailTemplate.vue @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/frontend/src/components/Settings/EmailTemplate/EmailTemplatePage.vue b/frontend/src/components/Settings/EmailTemplate/EmailTemplatePage.vue new file mode 100644 index 00000000..f41b4d5d --- /dev/null +++ b/frontend/src/components/Settings/EmailTemplate/EmailTemplatePage.vue @@ -0,0 +1,51 @@ + + + diff --git a/frontend/src/components/Settings/EmailTemplate/EmailTemplates.vue b/frontend/src/components/Settings/EmailTemplate/EmailTemplates.vue index 4ae30422..4eb9c622 100644 --- a/frontend/src/components/Settings/EmailTemplate/EmailTemplates.vue +++ b/frontend/src/components/Settings/EmailTemplate/EmailTemplates.vue @@ -15,7 +15,12 @@

-
@@ -100,27 +105,15 @@ @update:model-value="toggleEmailTemplate(template)" /> @@ -148,34 +141,18 @@ import { TextInput, FormControl, Switch, - createListResource, Dropdown, + FeatherIcon, } from 'frappe-ui' -import { ref, computed } from 'vue' +import { ref, computed, inject, h } from 'vue' -const templates = createListResource({ - type: 'list', - doctype: 'Email Template', - cache: 'emailTemplates', - fields: [ - 'name', - 'enabled', - 'use_html', - 'reference_doctype', - 'subject', - 'response', - 'response_html', - 'modified', - 'owner', - ], - auto: true, - filters: { reference_doctype: ['in', ['CRM Lead', 'CRM Deal']] }, - orderBy: 'modified desc', - pageLength: 20, -}) +const emit = defineEmits(['updateStep']) + +const templates = inject('templates') const search = ref('') const currentDoctype = ref('All') +const confirmDelete = ref(false) const templatesList = computed(() => { let list = templates.data || [] @@ -200,4 +177,89 @@ function toggleEmailTemplate(template) { enabled: template.enabled ? 1 : 0, }) } + +function deleteTemplate(template) { + confirmDelete.value = false + templates.delete.submit(template.name) +} + +function getDropdownOptions(template) { + let options = [ + { + label: __('Edit'), + component: (props) => + TemplateOption({ + option: __('Edit'), + icon: 'edit-2', + active: props.active, + onClick: () => { + emit('updateStep', 'edit-template', { ...template }) + }, + }), + }, + { + label: __('Duplicate'), + component: (props) => + TemplateOption({ + option: __('Duplicate'), + icon: 'copy', + active: props.active, + onClick: () => {}, + }), + }, + { + label: __('Delete'), + component: (props) => + TemplateOption({ + option: __('Delete'), + icon: 'trash-2', + active: props.active, + onClick: (e) => { + e.preventDefault() + e.stopPropagation() + confirmDelete.value = true + }, + }), + condition: () => !confirmDelete.value, + }, + { + label: __('Confirm Delete'), + component: (props) => + TemplateOption({ + option: __('Confirm Delete'), + icon: 'trash-2', + active: props.active, + variant: 'danger', + onClick: () => deleteTemplate(template), + }), + condition: () => confirmDelete.value, + }, + ] + + return options.filter((option) => option.condition?.() || true) +} + +function TemplateOption({ active, option, variant, icon, onClick }) { + return h( + 'button', + { + class: [ + active ? 'bg-surface-gray-2' : 'text-ink-gray-8', + 'group flex w-full gap-2 items-center rounded-md px-2 py-2 text-sm', + variant == 'danger' ? 'text-ink-red-3 hover:bg-ink-red-1' : '', + ], + onClick: onClick, + }, + [ + icon + ? h(FeatherIcon, { + name: icon, + class: ['h-4 w-4 shrink-0'], + 'aria-hidden': true, + }) + : null, + h('span', { class: 'whitespace-nowrap' }, option), + ], + ) +} diff --git a/frontend/src/components/Settings/EmailTemplate/NewEmailTemplate.vue b/frontend/src/components/Settings/EmailTemplate/NewEmailTemplate.vue new file mode 100644 index 00000000..b3ee3954 --- /dev/null +++ b/frontend/src/components/Settings/EmailTemplate/NewEmailTemplate.vue @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/src/components/Settings/Settings.vue b/frontend/src/components/Settings/Settings.vue index e0939285..57606486 100644 --- a/frontend/src/components/Settings/Settings.vue +++ b/frontend/src/components/Settings/Settings.vue @@ -51,7 +51,7 @@ import InviteUserPage from '@/components/Settings/InviteUserPage.vue' import ProfileSettings from '@/components/Settings/ProfileSettings.vue' import WhatsAppSettings from '@/components/Settings/WhatsAppSettings.vue' import ERPNextSettings from '@/components/Settings/ERPNextSettings.vue' -import EmailTemplates from '@/components/Settings/EmailTemplate/EmailTemplates.vue' +import EmailTemplatePage from '@/components/Settings/EmailTemplate/EmailTemplatePage.vue' import TelephonySettings from '@/components/Settings/TelephonySettings.vue' import EmailConfig from '@/components/Settings/EmailConfig.vue' import SidebarLink from '@/components/SidebarLink.vue' @@ -111,7 +111,7 @@ const tabs = computed(() => { { label: __('Email Templates'), icon: Email2Icon, - component: markRaw(EmailTemplates), + component: markRaw(EmailTemplatePage), }, ], },