Skip to content

Commit

Permalink
fix(settings): emails actions a11y and design
Browse files Browse the repository at this point in the history
Signed-off-by: Grigorii K. Shartsev <[email protected]>
  • Loading branch information
ShGKme committed Mar 5, 2024
1 parent 7efb36b commit 680f439
Show file tree
Hide file tree
Showing 5 changed files with 194 additions and 265 deletions.
147 changes: 82 additions & 65 deletions apps/settings/src/components/PersonalInfo/EmailSection/Email.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
- @copyright 2021, Christopher Ng <[email protected]>
-
- @author Christopher Ng <[email protected]>
- @author Grigorii K. Shartsev <[email protected]>
-
- @license GNU AGPL version 3 or any later version
-
Expand All @@ -22,47 +23,45 @@

<template>
<div>
<div class="email">
<NcInputField :id="inputIdWithDefault"
ref="email"
autocapitalize="none"
autocomplete="email"
:error="hasError || !!helperText"
:helper-text="helperText || undefined"
:label="inputPlaceholder"
:placeholder="inputPlaceholder"
spellcheck="false"
:success="isSuccess"
type="email"
:value.sync="emailAddress" />

<div class="email__actions">
<NcActions :aria-label="actionsLabel" @close="showFederationSettings = false">
<template v-if="showFederationSettings">
<NcActionButton @click="showFederationSettings = false">
<template #icon>
<NcIconSvgWrapper :path="mdiArrowLeft" />
</template>
{{ t('settings', 'Back') }}
</NcActionButton>
<FederationControlActions :readable="propertyReadable"
:additional="true"
:additional-value="email"
:disabled="federationDisabled"
:handle-additional-scope-change="saveAdditionalEmailScope"
:scope.sync="localScope"
@update:scope="onScopeChange" />
</template>
<template v-else>
<NcActionButton v-if="!federationDisabled && !primary"
@click="showFederationSettings = true">
<div class="email" :class="{ 'email--additional': !primary }">
<div v-if="!primary" class="email__label-container">
<label :for="inputIdWithDefault">{{ inputPlaceholder }}</label>
<FederationControl v-if="!federationDisabled && !primary"
:readable="propertyReadable"
:additional="true"
:additional-value="email"
:disabled="federationDisabled"
:handle-additional-scope-change="saveAdditionalEmailScope"
:scope.sync="localScope"
@update:scope="onScopeChange" />
</div>
<div class="email__input-container">
<NcTextField :id="inputIdWithDefault"
ref="email"
class="email__input"
autocapitalize="none"
autocomplete="email"
:error="hasError || !!helperText"
:helper-text="helperTextWithNonConfirmed"
label-outside
:placeholder="inputPlaceholder"
spellcheck="false"
:success="isSuccess"
type="email"
:value.sync="emailAddress" />

<div class="email__actions">
<NcActions :aria-label="actionsLabel">
<NcActionButton v-if="!primary || !isNotificationEmail"
close-after-click
:disabled="!isConfirmedAddress"
@click="setNotificationMail">
<template #icon>
<NcIconSvgWrapper :path="mdiLock" />
<NcIconSvgWrapper v-if="isNotificationEmail" :path="mdiStar" />
<NcIconSvgWrapper v-else :path="mdiStarOutline" />
</template>
{{ t('settings', 'Change scope level of {property}', { property: propertyReadable.toLocaleLowerCase() }) }}
{{ setNotificationMailLabel }}
</NcActionButton>
<NcActionCaption v-if="!isConfirmedAddress"
:name="t('settings', 'This address is not confirmed')" />
<NcActionButton close-after-click
:disabled="deleteDisabled"
@click="deleteEmail">
Expand All @@ -71,18 +70,8 @@
</template>
{{ deleteEmailLabel }}
</NcActionButton>
<NcActionButton v-if="!primary || !isNotificationEmail"
close-after-click
:disabled="!isConfirmedAddress"
@click="setNotificationMail">
<template #icon>
<NcIconSvgWrapper v-if="isNotificationEmail" :path="mdiStar" />
<NcIconSvgWrapper v-else :path="mdiStarOutline" />
</template>
{{ setNotificationMailLabel }}
</NcActionButton>
</template>
</NcActions>
</NcActions>
</div>
</div>
</div>

Expand All @@ -95,13 +84,14 @@
<script>
import NcActions from '@nextcloud/vue/dist/Components/NcActions.js'
import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton.js'
import NcActionCaption from '@nextcloud/vue/dist/Components/NcActionCaption.js'
import NcIconSvgWrapper from '@nextcloud/vue/dist/Components/NcIconSvgWrapper.js'
import NcInputField from '@nextcloud/vue/dist/Components/NcInputField.js'
import NcTextField from '@nextcloud/vue/dist/Components/NcTextField.js'
import debounce from 'debounce'
import { mdiArrowLeft, mdiLock, mdiStar, mdiStarOutline, mdiTrashCan } from '@mdi/js'
import FederationControlActions from '../shared/FederationControlActions.vue'
import FederationControl from '../shared/FederationControl.vue'
import { handleError } from '../../../utils/handlers.js'
import { ACCOUNT_PROPERTY_READABLE_ENUM, VERIFICATION_ENUM } from '../../../constants/AccountPropertyConstants.js'
Expand All @@ -121,10 +111,9 @@ export default {
components: {
NcActions,
NcActionButton,
NcActionCaption,
NcIconSvgWrapper,
NcInputField,
FederationControlActions,
NcTextField,
FederationControl,
},
props: {
Expand Down Expand Up @@ -213,6 +202,20 @@ export default {
return this.primary || this.localVerificationState === VERIFICATION_ENUM.VERIFIED
},
isNotConfirmedHelperText() {
if (!this.isConfirmedAddress) {
return t('settings', 'This address is not confirmed')
}
return ''
},
helperTextWithNonConfirmed() {
if (this.helperText || this.hasError || this.isSuccess) {
return this.helperText || ''
}
return this.isNotConfirmedHelperText
},
setNotificationMailLabel() {
if (this.isNotificationEmail) {
return t('settings', 'Unset as primary email')
Expand Down Expand Up @@ -259,7 +262,8 @@ export default {
methods: {
debounceEmailChange: debounce(async function(email) {
this.helperText = this.$refs.email?.$refs.input?.validationMessage || null
// TODO: provide method to get native input in NcTextField
this.helperText = this.$refs.email.$refs.inputField.$refs.input.validationMessage || null
if (this.helperText !== null) {
return
}
Expand Down Expand Up @@ -403,16 +407,29 @@ export default {
<style lang="scss" scoped>
.email {
display: flex;
flex-direction: row;
align-items: start;
gap: 4px;
&__label-container {
height: var(--default-clickable-area);
display: flex;
flex-direction: row;
align-items: center;
gap: calc(var(--default-grid-baseline) * 2);
}
&__input-container {
position: relative;
}
&__input {
// TODO: provide a way to hide status icon or combine it with trailing button in NcInputField
:deep(.input-field__icon--trailing) {
display: none;
}
}
&__actions {
display: flex;
gap: 0 2px;
margin-right: 5px;
margin-top: 6px;
position: absolute;
inset-block-start: 0;
inset-inline-end: 0;
}
}
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
- @copyright 2021, Christopher Ng <[email protected]>
-
- @author Christopher Ng <[email protected]>
- @author Grigorii K. Shartsev <[email protected]>
-
- @license GNU AGPL version 3 or any later version
-
Expand All @@ -21,7 +22,7 @@
-->

<template>
<section>
<section class="section-emails">
<HeaderBar :input-id="inputId"
:readable="primaryEmail.readable"
:is-editable="true"
Expand All @@ -45,10 +46,10 @@
</span>

<template v-if="additionalEmails.length">
<em class="additional-emails-label">{{ t('settings', 'Additional emails') }}</em>
<!-- TODO use unique key for additional email when uniqueness can be guaranteed, see https://github.com/nextcloud/server/issues/26866 -->
<Email v-for="(additionalEmail, index) in additionalEmails"
:key="additionalEmail.key"
class="section-emails__additional-email"
:index="index"
:scope.sync="additionalEmail.scope"
:email.sync="additionalEmail.value"
Expand Down Expand Up @@ -196,12 +197,11 @@ export default {
</script>
<style lang="scss" scoped>
section {
.section-emails {
padding: 10px 10px;
.additional-emails-label {
display: block;
margin-top: 16px;
&__additional-email {
margin-top: calc(var(--default-grid-baseline) * 3);
}
}
</style>
Loading

0 comments on commit 680f439

Please sign in to comment.