Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/mail.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristoph Wurst <christoph@winzerhof-wurst.at>2022-02-28 20:35:09 +0300
committerChristoph Wurst <christoph@winzerhof-wurst.at>2022-04-01 13:41:28 +0300
commite99758216b0a6a02087143ff7a8e3e37ff097752 (patch)
tree29841b1d92de5bfc2dbfe50e697e52e531f572a1 /src
parent69fdf4d15ff150523a0946850c3f91e4209ae167 (diff)
Improve account setup error reporting
Co-authored-by: julia.kirschenheuter <julia.kirschenheuter@nextcloud.com> Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
Diffstat (limited to 'src')
-rw-r--r--src/components/AccountForm.vue153
-rw-r--r--src/views/Setup.vue41
2 files changed, 149 insertions, 45 deletions
diff --git a/src/components/AccountForm.vue b/src/components/AccountForm.vue
index 2fa0fc265..5e231dc55 100644
--- a/src/components/AccountForm.vue
+++ b/src/components/AccountForm.vue
@@ -13,15 +13,19 @@
:placeholder="t('mail', 'Name')"
:disabled="loading"
autofocus>
- <label for="auto-address">{{ t('mail', 'Mail Address') }}</label>
+ <label for="auto-address" class="account-form__label--required">{{ t('mail', 'Mail address') }}</label>
<input
id="auto-address"
- v-model="autoConfig.emailAddress"
+ v-model.lazy="autoConfig.emailAddress"
type="email"
- :placeholder="t('mail', 'Mail Address')"
+ :placeholder="t('mail', 'name@example.org')"
:disabled="loading"
- required>
- <label for="auto-password">{{ t('mail', 'Password') }}</label>
+ required
+ @blur="isValidEmail(autoConfig.emailAddress)">
+ <p v-if="!isValidEmail(autoConfig.emailAddress)" class="account-form--error">
+ {{ t('mail', 'Please enter an email of the format name@example.com') }}
+ </p>
+ <label for="auto-password" class="account-form__label--required">{{ t('mail', 'Password') }}</label>
<input
id="auto-password"
v-model="autoConfig.password"
@@ -38,17 +42,21 @@
type="text"
:placeholder="t('mail', 'Name')"
:disabled="loading">
- <label for="man-address">{{ t('mail', 'Mail Address') }}</label>
+ <label for="man-address" class="account-form__label--required">{{ t('mail', 'Mail address') }}</label>
<input
id="man-address"
- v-model="manualConfig.emailAddress"
+ v-model.lazy="manualConfig.emailAddress"
type="email"
- :placeholder="t('mail', 'Mail Address')"
+ :placeholder="t('mail', 'name@example.org')"
:disabled="loading"
- required>
+ required
+ @blur="isValidEmail(manualConfig.emailAddress)">
+ <p v-if="!isValidEmail(manualConfig.emailAddress)" class="account-form--error">
+ {{ t('mail', 'Please enter an email of the format name@example.com') }}
+ </p>
<h3>{{ t('mail', 'IMAP Settings') }}</h3>
- <label for="man-imap-host">{{ t('mail', 'IMAP Host') }}</label>
+ <label for="man-imap-host" class="account-form__label--required">{{ t('mail', 'IMAP Host') }}</label>
<input
id="man-imap-host"
v-model="manualConfig.imapHost"
@@ -56,7 +64,9 @@
:placeholder="t('mail', 'IMAP Host')"
:disabled="loading"
required>
- <h4>{{ t('mail', 'IMAP Security') }}</h4>
+ <h4 class="account-form__heading--required">
+ {{ t('mail', 'IMAP Security') }}
+ </h4>
<div class="flex-row">
<input
id="man-imap-sec-none"
@@ -95,7 +105,7 @@
for="man-imap-sec-tls"
:class="{primary: manualConfig.imapSslMode === 'tls'}">{{ t('mail', 'STARTTLS') }}</label>
</div>
- <label for="man-imap-port">{{ t('mail', 'IMAP Port') }}</label>
+ <label for="man-imap-port" class="account-form__label--required">{{ t('mail', 'IMAP Port') }}</label>
<input
id="man-imap-port"
v-model="manualConfig.imapPort"
@@ -103,7 +113,7 @@
:placeholder="t('mail', 'IMAP Port')"
:disabled="loading"
required>
- <label for="man-imap-user">{{ t('mail', 'IMAP User') }}</label>
+ <label for="man-imap-user" class="account-form__label--required">{{ t('mail', 'IMAP User') }}</label>
<input
id="man-imap-user"
v-model="manualConfig.imapUser"
@@ -111,7 +121,7 @@
:placeholder="t('mail', 'IMAP User')"
:disabled="loading"
required>
- <label for="man-imap-password">{{ t('mail', 'IMAP Password') }}</label>
+ <label for="man-imap-password" class="account-form__label--required">{{ t('mail', 'IMAP Password') }}</label>
<input
id="man-imap-password"
v-model="manualConfig.imapPassword"
@@ -121,7 +131,7 @@
required>
<h3>{{ t('mail', 'SMTP Settings') }}</h3>
- <label for="man-smtp-host">{{ t('mail', 'SMTP Host') }}</label>
+ <label for="man-smtp-host" class="account-form__label--required">{{ t('mail', 'SMTP Host') }}</label>
<input
id="man-smtp-host"
ref="smtpHost"
@@ -131,7 +141,9 @@
:placeholder="t('mail', 'SMTP Host')"
:disabled="loading"
required>
- <h4>{{ t('mail', 'SMTP Security') }}</h4>
+ <h4 class="account-form__heading--required">
+ {{ t('mail', 'SMTP Security') }}
+ </h4>
<div class="flex-row">
<input
id="man-smtp-sec-none"
@@ -170,7 +182,7 @@
for="man-smtp-sec-tls"
:class="{primary: manualConfig.smtpSslMode === 'tls'}">{{ t('mail', 'STARTTLS') }}</label>
</div>
- <label for="man-smtp-port">{{ t('mail', 'SMTP Port') }}</label>
+ <label for="man-smtp-port" class="account-form__label--required">{{ t('mail', 'SMTP Port') }}</label>
<input
id="man-smtp-port"
v-model="manualConfig.smtpPort"
@@ -178,7 +190,7 @@
:placeholder="t('mail', 'SMTP Port')"
:disabled="loading"
required>
- <label for="man-smtp-user">{{ t('mail', 'SMTP User') }}</label>
+ <label for="man-smtp-user" class="account-form__label--required">{{ t('mail', 'SMTP User') }}</label>
<input
id="man-smtp-user"
v-model="manualConfig.smtpUser"
@@ -186,7 +198,7 @@
:placeholder="t('mail', 'SMTP User')"
:disabled="loading"
required>
- <label for="man-smtp-password">{{ t('mail', 'SMTP Password') }}</label>
+ <label for="man-smtp-password" class="account-form__label--required">{{ t('mail', 'SMTP Password') }}</label>
<input
id="man-smtp-password"
v-model="manualConfig.smtpPassword"
@@ -196,12 +208,28 @@
required>
</Tab>
</Tabs>
- <slot name="feedback" />
- <input type="submit"
- class="primary"
- :disabled="loading"
- :value="submitButtonText"
- @click.prevent="onSubmit">
+ <div class="account-form__submit-buttons">
+ <button v-if="mode === 'auto'"
+ class="primary account-form__submit-button"
+ type="submit"
+ :disabled="isDisabledAuto"
+ @click.prevent="onSubmit">
+ <span v-if="loading" class="icon-loading-small account-form__submit-button__spinner" />
+ {{ submitButtonText }}
+ </button>
+
+ <button v-else-if="mode === 'manual'"
+ class="primary account-form__submit-button"
+ type="submit"
+ :disabled="isDisabledManual"
+ @click.prevent="onSubmit">
+ <span v-if="loading" class="icon-loading-small account-form__submit-button__spinner" />
+ {{ submitButtonText }}
+ </button>
+ </div>
+ <div class="account-form--feedback">
+ <slot name="feedback" />
+ </div>
</form>
</template>
@@ -266,13 +294,39 @@ export default {
smtpUser: fromAccountOr('smtpUser', ''),
smtpPassword: '',
},
- submitButtonText: this.account ? t('mail', 'Save') : t('mail', 'Connect'),
}
},
computed: {
settingsPage() {
return this.account !== undefined
},
+
+ isDisabledAuto() {
+ switch (this.mode === 'auto') {
+ case !this.autoConfig.emailAddress || !this.isValidEmail(this.autoConfig.emailAddress) || !this.autoConfig.password :
+ return true
+ }
+ return this.loading
+ },
+
+ isDisabledManual() {
+ switch (this.mode === 'manual') {
+ case !this.manualConfig.emailAddress || !this.isValidEmail(this.manualConfig.emailAddress)
+ || !this.manualConfig.imapHost || !this.manualConfig.imapPort
+ || !this.manualConfig.imapUser || !this.manualConfig.imapPassword
+ || !this.manualConfig.smtpHost || !this.manualConfig.smtpPort
+ || !this.manualConfig.smtpUser || !this.manualConfig.smtpPassword:
+ return true
+ }
+ return this.loading
+ },
+
+ submitButtonText() {
+ if (this.loading) {
+ return t('mail', 'Connecting')
+ }
+ return this.account ? t('mail', 'Save') : t('mail', 'Connect')
+ },
},
methods: {
onModeChanged(e) {
@@ -339,13 +393,17 @@ export default {
}
},
onSubmit(event) {
- console.debug('account form submitted', { event })
-
- this.loading = true
-
- this.saveChanges()
- .catch((error) => logger.error('could not save account details', { error }))
- .then(() => (this.loading = false))
+ if (!this.isDisabledManual || !this.isDisabledAuto) {
+ console.debug('account form submitted', { event })
+ this.loading = true
+ this.saveChanges()
+ .catch((error) => logger.error('could not save account details', { error }))
+ .then(() => (this.loading = false))
+ }
+ },
+ isValidEmail(email) {
+ const regExpEmail = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
+ return regExpEmail.test(email)
},
},
}
@@ -413,4 +471,33 @@ input[type='radio'][disabled] + label {
cursor: default;
opacity: 0.5;
}
+.account-form__label--required:after {
+ content:" *";
+}
+.account-form__heading--required:after {
+ content:" *";
+}
+.account-form__submit-buttons {
+ display: flex;
+ justify-content: center;
+ margin-top: 5px;
+}
+.account-form__submit-button {
+ display: flex;
+ align-items: center;
+}
+.account-form__submit-button__spinner {
+ margin: 0 10px 0 0;
+ height: auto;
+ width: auto;
+}
+.account-form--feedback {
+ color: var(--color-text-maxcontrast);
+ margin-top: 5px;
+ text-align: center;
+}
+.account-form--error {
+ text-align: left;
+ font-size: 14px;
+}
</style>
diff --git a/src/views/Setup.vue b/src/views/Setup.vue
index 647a50e5e..31285a9d7 100644
--- a/src/views/Setup.vue
+++ b/src/views/Setup.vue
@@ -1,14 +1,17 @@
<template>
<Content app-name="mail">
<Navigation v-if="hasAccounts" />
- <div id="emptycontent">
- <div class="icon-mail" />
- <h2>{{ t('mail', 'Connect your mail account') }}</h2>
- <AccountForm :display-name="displayName" :email="email" :save="onSave">
- <template v-if="error" #feedback class="warning">
- {{ error }}
+ <div class="mail-empty-content">
+ <EmptyContent icon="icon-mail">
+ <h2>{{ t('mail', 'Connect your mail account') }}</h2>
+ <template #desc>
+ <AccountForm :display-name="displayName" :email="email" :save="onSave">
+ <template v-if="error" #feedback class="warning">
+ {{ error }}
+ </template>
+ </AccountForm>
</template>
- </AccountForm>
+ </EmptyContent>
</div>
</Content>
</template>
@@ -19,6 +22,7 @@ import { loadState } from '@nextcloud/initial-state'
import { translate as t } from '@nextcloud/l10n'
import AccountForm from '../components/AccountForm'
+import EmptyContent from '@nextcloud/vue/dist/Components/EmptyContent'
import Navigation from '../components/Navigation'
import logger from '../logger'
@@ -27,6 +31,7 @@ export default {
components: {
AccountForm,
Content,
+ EmptyContent,
Navigation,
},
data() {
@@ -58,10 +63,22 @@ export default {
.catch((error) => {
logger.error('Could not create account', { error })
- if (error?.data?.message) {
- this.error = error.data.message
+ if (error.data?.error === 'AUTOCONFIG_FAILED') {
+ this.error = t('mail', 'Auto detect failed. Please try manual mode.')
+ } else if (error.data?.error === 'CONNECTION_ERROR') {
+ if (error.data.service === 'IMAP') {
+ this.error = t('mail', 'Manual config failed. IMAP server is not reachable.')
+ } else if (error.data.service === 'SMTP') {
+ this.error = t('mail', 'Manual config failed. SMTP server is not reachable.')
+ }
+ } else if (error.data?.error === 'AUTHENTICATION') {
+ if (error.data.service === 'IMAP') {
+ this.error = t('mail', 'Manual config failed. IMAP username or password is wrong.')
+ } else if (error.data.service === 'SMTP') {
+ this.error = t('mail', 'Manual config failed. SMTP username or password is wrong.')
+ }
} else {
- this.error = t('mail', 'Unexpected error during account creation')
+ this.error = t('mail', 'There was an error while setting up your account. Please try again.')
}
})
},
@@ -70,7 +87,7 @@ export default {
</script>
<style>
-#emptycontent {
- margin-top: 10vh;
+.mail-empty-content {
+ margin: 0 auto;
}
</style>