diff options
author | Christoph Wurst <christoph@winzerhof-wurst.at> | 2022-02-28 20:35:09 +0300 |
---|---|---|
committer | Christoph Wurst <christoph@winzerhof-wurst.at> | 2022-04-01 13:41:28 +0300 |
commit | e99758216b0a6a02087143ff7a8e3e37ff097752 (patch) | |
tree | 29841b1d92de5bfc2dbfe50e697e52e531f572a1 /src | |
parent | 69fdf4d15ff150523a0946850c3f91e4209ae167 (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.vue | 153 | ||||
-rw-r--r-- | src/views/Setup.vue | 41 |
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> |