chore: add localization support for email account settings

This commit is contained in:
Pratik 2025-04-22 15:33:28 +05:30
parent 001a6617f5
commit 5eb46f6b6c
5 changed files with 63 additions and 50 deletions

View File

@ -13,7 +13,7 @@
</div> </div>
</div> </div>
<div> <div>
<Badge variant="subtle" :label="badgeTitleColor" :theme="gray" /> <Badge variant="subtle" :label="badgeTitle" :theme="gray" />
</div> </div>
<!-- email id --> <!-- email id -->
</div> </div>
@ -31,18 +31,18 @@ const props = defineProps({
}, },
}) })
const badgeTitleColor = computed(() => { const badgeTitle = computed(() => {
if ( if (
props.emailAccount.default_incoming && props.emailAccount.default_incoming &&
props.emailAccount.default_outgoing props.emailAccount.default_outgoing
) { ) {
return 'Default Sending and Inbox' return __('Default Sending and Inbox')
} else if (props.emailAccount.default_incoming) { } else if (props.emailAccount.default_incoming) {
return 'Default Inbox' return __('Default Inbox')
} else if (props.emailAccount.default_outgoing) { } else if (props.emailAccount.default_outgoing) {
return 'Default Sending' return __('Default Sending')
} else { } else {
return 'Inbox' return __('Inbox')
} }
}) })
</script> </script>

View File

@ -3,10 +3,10 @@
<!-- header --> <!-- header -->
<div class="flex items-center justify-between text-ink-gray-9"> <div class="flex items-center justify-between text-ink-gray-9">
<h2 class="flex gap-2 text-xl font-semibold leading-none h-5"> <h2 class="flex gap-2 text-xl font-semibold leading-none h-5">
Email Accounts {{ __('Email Accounts') }}
</h2> </h2>
<Button <Button
label="Add Account" :label="__('Add Account')"
theme="gray" theme="gray"
variant="solid" variant="solid"
@click="emit('update:step', 'email-add')" @click="emit('update:step', 'email-add')"
@ -31,7 +31,7 @@
</div> </div>
<!-- fallback if no email accounts --> <!-- fallback if no email accounts -->
<div v-else class="flex items-center justify-center h-64 text-gray-500"> <div v-else class="flex items-center justify-center h-64 text-gray-500">
Please add an email account to continue. {{ __('Please add an email account to continue.') }}
</div> </div>
</div> </div>
</template> </template>

View File

@ -2,9 +2,11 @@
<div class="flex flex-col h-full gap-4"> <div class="flex flex-col h-full gap-4">
<!-- title and desc --> <!-- title and desc -->
<div role="heading" aria-level="1" class="flex flex-col gap-1"> <div role="heading" aria-level="1" class="flex flex-col gap-1">
<h2 class="text-xl font-semibold text-ink-gray-9">Setup Email</h2> <h2 class="text-xl font-semibold text-ink-gray-9">
{{ __('Setup Email') }}
</h2>
<p class="text-sm text-gray-600"> <p class="text-sm text-gray-600">
Choose the email service provider you want to configure. {{ __('Choose the email service provider you want to configure.') }}
</p> </p>
</div> </div>
<!-- email service provider selection --> <!-- email service provider selection -->
@ -138,14 +140,14 @@ const addEmailRes = createResource({
}, },
onSuccess: () => { onSuccess: () => {
createToast({ createToast({
title: 'Email account created successfully', title: __('Email account created successfully'),
icon: 'check', icon: 'check',
iconClasses: 'text-green-600', iconClasses: 'text-green-600',
}) })
emit('update:step', 'email-list') emit('update:step', 'email-list')
}, },
onError: () => { onError: () => {
error.value = 'Failed to create email account, Invalid credentials' error.value = __('Failed to create email account, Invalid credentials')
}, },
}) })

View File

@ -2,7 +2,9 @@
<div class="flex flex-col h-full gap-4"> <div class="flex flex-col h-full gap-4">
<!-- title and desc --> <!-- title and desc -->
<div role="heading" aria-level="1" class="flex justify-between gap-1"> <div role="heading" aria-level="1" class="flex justify-between gap-1">
<h2 class="text-xl font-semibold text-ink-gray-9">Edit Email</h2> <h2 class="text-xl font-semibold text-ink-gray-9">
{{ __('Edit Email') }}
</h2>
</div> </div>
<div class="w-fit"> <div class="w-fit">
<EmailProviderIcon <EmailProviderIcon
@ -19,7 +21,9 @@
/> />
<div class="text-xs text-gray-700 dark:text-gray-500 text-wrap"> <div class="text-xs text-gray-700 dark:text-gray-500 text-wrap">
{{ info.description }} {{ info.description }}
<a :href="info.link" target="_blank" class="underline">here</a> <a :href="info.link" target="_blank" class="underline">{{
__('here')
}}</a>
. .
</div> </div>
</div> </div>
@ -60,14 +64,14 @@
<!-- action buttons --> <!-- action buttons -->
<div class="flex justify-between mt-auto"> <div class="flex justify-between mt-auto">
<Button <Button
label="Back" :label="__('Back')"
theme="gray" theme="gray"
variant="outline" variant="outline"
:disabled="loading" :disabled="loading"
@click="emit('update:step', 'email-list')" @click="emit('update:step', 'email-list')"
/> />
<Button <Button
label="Update Account" :label="__('Update Account')"
variant="solid" variant="solid"
@click="updateAccount" @click="updateAccount"
:loading="loading" :loading="loading"
@ -112,7 +116,7 @@ const state = reactive({
}) })
const info = { const info = {
description: 'To know more about setting up email accounts, click', description: __('To know more about setting up email accounts, click'),
link: 'https://docs.erpnext.com/docs/user/manual/en/email-account', link: 'https://docs.erpnext.com/docs/user/manual/en/email-account',
} }
@ -145,7 +149,7 @@ async function updateAccount() {
if (!nameChanged && !otherFieldsChanged) { if (!nameChanged && !otherFieldsChanged) {
createToast({ createToast({
title: 'No changes made', title: __('No changes made'),
icon: 'info', icon: 'info',
iconClasses: 'text-blue-600', iconClasses: 'text-blue-600',
}) })
@ -207,7 +211,7 @@ async function callSetValue(values) {
function succesHandler() { function succesHandler() {
emit('update:step', 'email-list') emit('update:step', 'email-list')
createToast({ createToast({
title: 'Email account updated successfully', title: __('Email account updated successfully'),
icon: 'check', icon: 'check',
iconClasses: 'text-green-600', iconClasses: 'text-green-600',
}) })
@ -215,6 +219,6 @@ function succesHandler() {
function errorHandler() { function errorHandler() {
loading.value = false loading.value = false
error.value = 'Failed to update email account, Invalid credentials' error.value = __('Failed to update email account, Invalid credentials')
} }
</script> </script>

View File

@ -10,10 +10,10 @@ import LogoFrappeMail from '@/images/frappe-mail.svg'
const fixedFields = [ const fixedFields = [
{ {
label: 'Account Name', label: __('Account Name'),
name: 'email_account_name', name: 'email_account_name',
type: 'text', type: 'text',
placeholder: 'Support / Sales', placeholder: __('Support / Sales'),
}, },
{ {
label: 'Email ID', label: 'Email ID',
@ -25,38 +25,43 @@ const fixedFields = [
export const incomingOutgoingFields = [ export const incomingOutgoingFields = [
{ {
label: 'Enable Incoming', label: __('Enable Incoming'),
name: 'enable_incoming', name: 'enable_incoming',
type: 'checkbox', type: 'checkbox',
description: description: __(
'If enabled, records can be created from the incoming emails on this account.', 'If enabled, records can be created from the incoming emails on this account.',
),
}, },
{ {
label: 'Enable Outgoing', label: __('Enable Outgoing'),
name: 'enable_outgoing', name: 'enable_outgoing',
type: 'checkbox', type: 'checkbox',
description: 'If enabled, outgoing emails can be sent from this account.', description: __(
'If enabled, outgoing emails can be sent from this account.',
),
}, },
{ {
label: 'Default Incoming', label: __('Default Incoming'),
name: 'default_incoming', name: 'default_incoming',
type: 'checkbox', type: 'checkbox',
description: description: __(
'If enabled, all replies to your company (eg: replies@yourcomany.com) will come to this account. Note: Only one account can be default incoming.', 'If enabled, all replies to your company (eg: replies@yourcomany.com) will come to this account. Note: Only one account can be default incoming.',
),
}, },
{ {
label: 'Default Outgoing', label: __('Default Outgoing'),
name: 'default_outgoing', name: 'default_outgoing',
type: 'checkbox', type: 'checkbox',
description: description: __(
'If enabled, all outgoing emails will be sent from this account. Note: Only one account can be default outgoing.', 'If enabled, all outgoing emails will be sent from this account. Note: Only one account can be default outgoing.',
),
}, },
] ]
export const popularProviderFields = [ export const popularProviderFields = [
...fixedFields, ...fixedFields,
{ {
label: 'Password', label: __('Password'),
name: 'password', name: 'password',
type: 'password', type: 'password',
placeholder: '********', placeholder: '********',
@ -89,55 +94,57 @@ export const services = [
{ {
name: 'GMail', name: 'GMail',
icon: LogoGmail, icon: LogoGmail,
info: `Setting up GMail requires you to enable two factor authentication info: __(`Setting up GMail requires you to enable two factor authentication
and app specific passwords. Read more`, and app specific passwords. Read more`),
link: 'https://support.google.com/accounts/answer/185833', link: 'https://support.google.com/accounts/answer/185833',
custom: false, custom: false,
}, },
{ {
name: 'Outlook', name: 'Outlook',
icon: LogoOutlook, icon: LogoOutlook,
info: `Setting up Outlook requires you to enable two factor authentication info: __(`Setting up Outlook requires you to enable two factor authentication
and app specific passwords. Read more`, and app specific passwords. Read more`),
link: 'https://support.microsoft.com/en-us/account-billing/how-to-get-and-use-app-passwords-5896ed9b-4263-e681-128a-a6f2979a7944', link: 'https://support.microsoft.com/en-us/account-billing/how-to-get-and-use-app-passwords-5896ed9b-4263-e681-128a-a6f2979a7944',
custom: false, custom: false,
}, },
{ {
name: 'Sendgrid', name: 'Sendgrid',
icon: LogoSendgrid, icon: LogoSendgrid,
info: `Setting up Sendgrid requires you to enable two factor authentication info: __(`Setting up Sendgrid requires you to enable two factor authentication
and app specific passwords. Read more `, and app specific passwords. Read more `),
link: 'https://sendgrid.com/docs/ui/account-and-settings/two-factor-authentication/', link: 'https://sendgrid.com/docs/ui/account-and-settings/two-factor-authentication/',
custom: false, custom: false,
}, },
{ {
name: 'SparkPost', name: 'SparkPost',
icon: LogoSparkpost, icon: LogoSparkpost,
info: `Setting up SparkPost requires you to enable two factor authentication info: __(`Setting up SparkPost requires you to enable two factor authentication
and app specific passwords. Read more `, and app specific passwords. Read more `),
link: 'https://support.sparkpost.com/docs/my-account-and-profile/enabling-two-factor-authentication', link: 'https://support.sparkpost.com/docs/my-account-and-profile/enabling-two-factor-authentication',
custom: false, custom: false,
}, },
{ {
name: 'Yahoo', name: 'Yahoo',
icon: LogoYahoo, icon: LogoYahoo,
info: `Setting up Yahoo requires you to enable two factor authentication info: __(`Setting up Yahoo requires you to enable two factor authentication
and app specific passwords. Read more `, and app specific passwords. Read more `),
link: 'https://help.yahoo.com/kb/SLN15241.html', link: 'https://help.yahoo.com/kb/SLN15241.html',
custom: false, custom: false,
}, },
{ {
name: 'Yandex', name: 'Yandex',
icon: LogoYandex, icon: LogoYandex,
info: `Setting up Yandex requires you to enable two factor authentication info: __(`Setting up Yandex requires you to enable two factor authentication
and app specific passwords. Read more `, and app specific passwords. Read more `),
link: 'https://yandex.com/support/id/authorization/app-passwords.html', link: 'https://yandex.com/support/id/authorization/app-passwords.html',
custom: false, custom: false,
}, },
{ {
name: 'Frappe Mail', name: 'Frappe Mail',
icon: LogoFrappeMail, icon: LogoFrappeMail,
info: `Setting up Frappe Mail requires you to have an API key and API Secret of your email account. Read more `, info: __(
`Setting up Frappe Mail requires you to have an API key and API Secret of your email account. Read more `,
),
link: 'https://github.com/frappe/mail', link: 'https://github.com/frappe/mail',
custom: true, custom: true,
}, },
@ -155,21 +162,21 @@ export const emailIcon = {
export function validateInputs(state, isCustom) { export function validateInputs(state, isCustom) {
if (!state.email_account_name) { if (!state.email_account_name) {
return 'Account name is required' return __('Account name is required')
} }
if (!state.email_id) { if (!state.email_id) {
return 'Email ID is required' return __('Email ID is required')
} }
const validEmail = validateEmail(state.email_id) const validEmail = validateEmail(state.email_id)
if (!validEmail) { if (!validEmail) {
return 'Invalid email ID' return __('Invalid email ID')
} }
if (!isCustom && !state.password) { if (!isCustom && !state.password) {
return 'Password is required' return __('Password is required')
} }
if (isCustom) { if (isCustom) {
if (!state.api_key) { if (!state.api_key) {
return 'API Key is required' return __('API Key is required')
} }
if (!state.api_secret) { if (!state.api_secret) {
return return