-
-
-
- verified
-
-
- Additional emails cannot be duplicated
-
-
- An email is required
-
-
- Invalid email format
-
-
-
- This email is already associated with an ORCID record.
-
-
-
-
+
+
+
- verified
- Other email addresses Verification email sent
- {{ emailsForm.value[email.putCode].email }}
-
-
-
-
+
+ An email is required
+
+
+ Email can not be duplicated
+
+
+ Invalid email format
+
-
+ This email is already associated with an ORCID record.
+
-
-
- Only verified email addresses can be displayed publicly or shared
- with trusted parties. Please verify your email
-
-
-
-
- We’ve sent a verification email to
- {{ email.value }}
-
- Please check your email inbox (or maybe your spam folder) for an
- email with a link to complete the process.
-
-
+
-
-
- You haven’t added any other email addresses yet.
-
-
-
-
-
+
+
+
-
- info
-
-
-
- Adding additional email addresses is not allowed when you are
- managing another ORCID record.
-
-
+ Email notifications
+
+
+
+ Which verified email address should we send your ORCID notifications
+ to? You can change the frequency of these notification emails in
+
+ your ORCID account settings.
+
+
+
+
+
+ {{ email.value }}
+
+
+
diff --git a/src/app/cdk/side-bar/modals/modal-email/modal-email.component.scss b/src/app/cdk/side-bar/modals/modal-email/modal-email.component.scss
index 3e008cb04d..83c31aba76 100644
--- a/src/app/cdk/side-bar/modals/modal-email/modal-email.component.scss
+++ b/src/app/cdk/side-bar/modals/modal-email/modal-email.component.scss
@@ -2,47 +2,44 @@
padding-inline-start: 0;
}
-.orcid-works-best {
- margin-bottom: 16px;
-}
-
-.terms-of-use {
- margin-top: 0;
+.description {
+ margin: 0 0 16px 0;
+ line-height: 21px;
}
-.add-more-email {
- display: flex;
- align-items: center;
-
- mat-icon {
- margin-inline-end: 8px;
+app-alert-message {
+ p {
+ margin: 8px 0 0 0;
+ letter-spacing: 0.25px;
}
+ line-height: 24px;
+ margin-bottom: 16px;
+ margin-top: 32px;
}
-.email-input-line {
- justify-content: space-between;
- align-items: center;
+.verification-icon {
+ height: 40px;
+ width: 32px;
+ font-size: 32px;
+ margin-right: 16px;
+ align-content: center;
}
mat-form-field {
width: 100%;
- top: 12px;
+ line-height: 20px;
+ margin: 0;
mat-icon {
line-height: 1.1;
}
}
-.visibility-wrapper {
- width: 60%;
-}
-
-.url-wrapper {
- width: 40%;
-}
-
.actions-wrapper {
width: 51%;
+ margin-left: 48px;
+ margin-top: 3px;
+ line-height: 21px;
}
.actions-wrapper,
@@ -50,7 +47,6 @@ mat-form-field {
display: flex;
flex-wrap: nowrap;
flex-shrink: 0;
- align-items: center;
justify-content: space-between;
.actions-sub-wrapper {
@@ -68,131 +64,117 @@ mat-form-field {
}
}
-.primary-email-label {
- display: flex;
+.email-input-line {
align-items: center;
- word-break: break-all;
+ height: 44px;
+}
- mat-icon {
- margin-inline-start: 6px;
- margin-inline-end: 16px;
- width: 32px;
- }
+.email-entry {
+ margin-top: 16px;
+ margin-bottom: 16px;
+}
- mat-icon,
- .other-names {
- margin-inline-start: 12px;
- }
+.separator {
+ height: 1px;
+ width: 100%;
+ margin: 0;
}
-.email-input-line {
- margin-top: 5px;
- margin-bottom: 8px;
-
- img {
- margin-top: 6px;
- cursor: move;
- z-index: 1;
- margin-inline-end: 18px;
+.email-list {
+ margin-bottom: 32px;
+
+ ::ng-deep .mat-form-field-flex {
+ margin-top: 0;
}
- .email-activated {
- margin-bottom: 12px;
- margin-top: 10px;
+ ::ng-deep .mat-form-field-subscript-wrapper {
+ padding: 0 !important;
+ margin-top: 4px;
}
-}
-::ng-deep .columns-4-or-8 .mat-form-field {
- margin-inline-end: auto;
+ ::ng-deep .mat-form-field-wrapper {
+ padding-bottom: 0;
+ }
}
.email-input-container {
- max-width: 49%;
+ flex-grow: 1;
padding-inline-end: 24px;
+ width: 0;
+}
+
+.select-notifications-email {
+ padding: 0 8px 0 8px;
+ align-items: center;
+ display: flex;
+ height: 38px;
+ max-width: 402px;
+ width: auto;
+ border: solid 1px;
+ border-radius: 0 5px 5px 0;
+}
+.current-notification-email {
+ font-weight: bold;
+}
+
+.disabled-select-notifications-email {
+ ::ng-deep .mat-select-trigger {
+ cursor: default;
+ }
}
.add-more {
margin-top: 16px;
-
+ align-items: center;
+ text-decoration: underline;
mat-icon {
padding-inline-end: 8px;
}
}
-::ng-deep app-alert-message {
- p {
- margin: 0;
+.verified-email {
+ em,
+ strong {
+ display: block;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
}
-
- p.email-container {
- margin: 16px 0 16px 0;
+ strong {
+ margin-bottom: 2px;
}
-
- margin-bottom: 20px;
+ line-height: 21px;
+ letter-spacing: 0.25px;
}
-::ng-deep .columns-4-or-8 {
- .mat-form-field {
- margin-inline-end: auto;
- }
-
- .email-input-container {
- padding: 0;
- max-width: 100%;
- padding-inline-end: 0;
- }
-
- .actions-wrapper,
- .actions-sub-wrapper {
- width: 100%;
- flex-wrap: wrap;
- }
-
- .actions-sub-wrapper {
- justify-content: space-between !important;
- }
+.visibility-hidden {
+ justify-content: end !important;
}
-.additional-email {
- ::ng-deep .mat-form-field-wrapper {
- padding-bottom: 18px !important;
+.delete-button {
+ margin-inline-start: 16px;
+ margin-inline-end: 16px;
+ mat-icon {
+ font-size: 24px;
+ margin-top: -4px;
}
}
-.only-verified {
- padding: 0 4px;
-}
-
-.visibility-hidden {
- justify-content: end !important;
+.email-notfications-header {
+ margin-bottom: 16px;
}
-.info {
- padding: 16px;
- margin-top: 32px;
- border: solid 2px;
- border-radius: 4px;
- height: 30px;
- display: flex;
- align-items: center;
-
- p {
- margin: 0;
+.email-notifications-description {
+ a {
+ text-decoration: underline;
}
-}
-
-.delete-button {
- margin-inline-start: 16px;
+ margin-bottom: 32px;
}
app-visibility-selector {
- margin-inline-start: 16px;
+ margin-inline-start: 8px;
}
-::ng-deep .columns-4-or-8 {
- app-visibility-selector {
- margin-inline-start: 0;
- margin-top: 16px;
- margin-bottom: 16px;
- }
+::ng-deep .main-button-container {
+ height: 100%;
}
diff --git a/src/app/cdk/side-bar/modals/modal-email/modal-email.component.scss-theme.scss b/src/app/cdk/side-bar/modals/modal-email/modal-email.component.scss-theme.scss
index 07a389f61e..998cf07b3c 100644
--- a/src/app/cdk/side-bar/modals/modal-email/modal-email.component.scss-theme.scss
+++ b/src/app/cdk/side-bar/modals/modal-email/modal-email.component.scss-theme.scss
@@ -18,6 +18,30 @@
color: mat.get-color-from-palette($primary, 700);
}
+ .verification-icon {
+ color: mat.get-color-from-palette($background, 'ui-background-light');
+ }
+ .verified {
+ color: mat.get-color-from-palette($foreground, 'brand-primary');
+ }
+
+ .separator {
+ background: mat.get-color-from-palette($background, 'ui-background-light');
+ }
+
+ .select-notifications-email {
+ ::ng-deep .mat-select-placeholder {
+ color: black;
+ }
+ color: rgba(0, 0, 0, 0.12);
+ }
+
+ .disabled-select-notifications-email {
+ ::ng-deep .mat-select-placeholder {
+ color: rgba(black, 0.6);
+ }
+ }
+
.info {
border-color: mat.get-color-from-palette(
$foreground,
diff --git a/src/app/cdk/side-bar/modals/modal-email/modal-email.component.spec.ts b/src/app/cdk/side-bar/modals/modal-email/modal-email.component.spec.ts
index 12a069e695..00e7ca8375 100644
--- a/src/app/cdk/side-bar/modals/modal-email/modal-email.component.spec.ts
+++ b/src/app/cdk/side-bar/modals/modal-email/modal-email.component.spec.ts
@@ -4,7 +4,6 @@ import { ModalEmailComponent } from './modal-email.component'
import { HttpClientTestingModule } from '@angular/common/http/testing'
import { RouterTestingModule } from '@angular/router/testing'
import { WINDOW_PROVIDERS } from '../../../window'
-import { RegisterService } from '../../../../core/register/register.service'
import { PlatformInfoService } from '../../../platform-info'
import { ErrorHandlerService } from '../../../../core/error-handler/error-handler.service'
import { SnackbarService } from '../../../snackbar/snackbar.service'
@@ -15,6 +14,7 @@ import {
MatLegacyDialogRef as MatDialogRef,
} from '@angular/material/legacy-dialog'
import { Overlay } from '@angular/cdk/overlay'
+import { AlertMessageModule } from 'src/app/cdk/alert-message/alert-message.module'
describe('ModalEmailComponent', () => {
let component: ModalEmailComponent
@@ -22,7 +22,11 @@ describe('ModalEmailComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
- imports: [HttpClientTestingModule, RouterTestingModule],
+ imports: [
+ HttpClientTestingModule,
+ RouterTestingModule,
+ AlertMessageModule,
+ ],
declarations: [ModalEmailComponent],
providers: [
{ provide: MAT_DIALOG_DATA, useValue: {} },
diff --git a/src/app/cdk/side-bar/modals/modal-email/modal-email.component.ts b/src/app/cdk/side-bar/modals/modal-email/modal-email.component.ts
index 36874f195f..6f25d97040 100644
--- a/src/app/cdk/side-bar/modals/modal-email/modal-email.component.ts
+++ b/src/app/cdk/side-bar/modals/modal-email/modal-email.component.ts
@@ -46,6 +46,7 @@ export class ModalEmailComponent implements OnInit, OnDestroy {
ariaLabelKnowledgeSupport = $localize`:@@side-bar.ariaLabelOrcidTermsSupport:ORCID support page (Opens in a new tab)`
ariaLabelOrcidTermsOfUseLink = $localize`:@@side-bar.ariaLabelOrcidTermsOfUseLink:ORCID terms of use (Opens in a new tab)`
ariaLabelSave = $localize`:@@side-bar.ariaLabelEmailSave:Save changes to Emails`
+ ariaLabelSelect = $localize`:@@side-bar.ariaLabelEmailSave:Select email to receive notifications`
ariaLabelCancel = $localize`:@@side-bar.ariaLabelEmailCancel:Cancel changes and close Emails`
ariaLabelDelete = $localize`:@@side-bar.ariaLabelEmailDelete:Delete Email`
ariaLabelClose = $localize`:@@side-bar.ariaLabelEmailClose:Close Emails`
@@ -57,6 +58,11 @@ export class ModalEmailComponent implements OnInit, OnDestroy {
ariaLabelVisibilityOtherEmailPublic = $localize`:@@side-bar.ariaLabelOtherEmailPublic:Set other email visibility to Everyone`
ariaLabelVisibilityOtherEmailTrustedParty = $localize`:@@side-bar.ariaLabelOtherEmailTrustedParties:Set other email visibility to Trusted Parties`
ariaLabelVisibilityOtherEmailPrivate = $localize`:@@side-bar.ariaLabelOtherEmailPrivate:Set other email visibility to Only Me`
+ ariaLabelVisibilityEmailPublic = $localize`:@@side-bar.ariaLabelEmailPublic:Set email visibility to Everyone`
+ ariaLabelVisibilityEmailTrustedParty = $localize`:@@side-bar.ariaLabelEmailTrustedParties:Set email visibility to Trusted Parties`
+ ariaLabelVisibilityEmailPrivate = $localize`:@@side-bar.ariaLabelEmailPrivate:Set email visibility to Only Me`
+ deleteTooltip = $localize`:@@side-bar.deleteTooltip:You can't delete the only email address in your account`
+ visibilityTooltip = $localize`:@@side-bar.visibilityTooltip:Visibility set to Only me`
@ViewChildren('emailInput') inputs: QueryList
verificationsSend: string[] = []
@@ -64,6 +70,7 @@ export class ModalEmailComponent implements OnInit, OnDestroy {
addedEmailsCount = 0
emailsForm: UntypedFormGroup = new UntypedFormGroup({})
emails: AssertionVisibilityString[] = []
+ primaryEmail: AssertionVisibilityString | undefined = undefined
originalEmailsBackendCopy: AssertionVisibilityString[]
defaultVisibility: VisibilityStrings = 'PRIVATE'
@@ -171,11 +178,16 @@ export class ModalEmailComponent implements OnInit, OnDestroy {
// Add email to the emails list
// backend response come with no email putCode, so here we create one to be able to track those on the frontend
- this.emails.push({
+ const emailEntry: AssertionVisibilityString = {
putCode: newPutCode,
action: existingEmail ? 'UPDATE' : 'ADD',
...existingEmail,
- } as AssertionVisibilityString)
+ }
+ this.emails.push(emailEntry)
+
+ if (existingEmail && emailEntry.primary) {
+ this.primaryEmail = emailEntry
+ }
// Add a new control to the formGroup
this.emailsForm.addControl(
@@ -199,7 +211,9 @@ export class ModalEmailComponent implements OnInit, OnDestroy {
}
),
visibility: new UntypedFormControl(
- existingEmail ? existingEmail.visibility : this.defaultVisibility,
+ existingEmail && existingEmail.verified
+ ? existingEmail.visibility
+ : this.defaultVisibility,
{
validators: [this.emailsIsUnverified(newPutCode)],
}
@@ -225,12 +239,23 @@ export class ModalEmailComponent implements OnInit, OnDestroy {
* @param newPrimaryEmail: the email to make primary
*/
makePrimary(newPrimaryEmail: AssertionVisibilityString): void {
+ this.primaryEmail = newPrimaryEmail
this.emails.forEach(
(email) => (email.primary = email.putCode === newPrimaryEmail.putCode)
)
this.triggerGeneralFormValidation()
}
+ setNextEmailAsPrimary() {
+ const verifiedEmails = this.emails.filter((email) => email.verified)
+ const currentIndex = verifiedEmails.findIndex(
+ (value) => value.putCode === this.primaryEmail.putCode
+ )
+ const nextIndex = (currentIndex + 1) % verifiedEmails.length
+ const nextEmail = verifiedEmails[nextIndex]
+ this.makePrimary(nextEmail)
+ }
+
private triggerGeneralFormValidation() {
Object.keys(this.emailsForm.controls).forEach((currentControlKey) => {
;(
@@ -373,9 +398,15 @@ export class ModalEmailComponent implements OnInit, OnDestroy {
}
deleteEmail(controlKey: string) {
- const i = this.emails.findIndex((value) => value.putCode === controlKey)
- this.emails.splice(i, 1)
- this.emailsForm.removeControl(controlKey)
+ if (!this.hasOneEmailAddress(controlKey)) {
+ if (controlKey === this.primaryEmail?.putCode) {
+ this.setNextEmailAsPrimary()
+ }
+
+ const i = this.emails.findIndex((value) => value.putCode === controlKey)
+ this.emails.splice(i, 1)
+ this.emailsForm.removeControl(controlKey)
+ }
}
showNonVerifiedData(controlKey: string, otherEmail?: boolean): boolean {
@@ -458,6 +489,20 @@ export class ModalEmailComponent implements OnInit, OnDestroy {
return result
}
+ hasOneEmailAddress(controlKey = ''): boolean {
+ if (controlKey.startsWith('new')) {
+ return false
+ }
+ return (
+ this.emails.filter((email) => !email.putCode.startsWith('newEmailInput'))
+ .length === 1
+ )
+ }
+
+ hasVerifiedEmailAddress(): boolean {
+ return this.emails.some((email) => email.verified)
+ }
+
ngOnDestroy() {
this.$destroy.next(true)
this.$destroy.unsubscribe()
diff --git a/src/app/cdk/side-bar/side-bar.module.ts b/src/app/cdk/side-bar/side-bar.module.ts
index 2a1e16962b..52c284ceef 100644
--- a/src/app/cdk/side-bar/side-bar.module.ts
+++ b/src/app/cdk/side-bar/side-bar.module.ts
@@ -21,6 +21,7 @@ import { SharedModule } from 'src/app/shared/shared.module'
import { FormDirectivesModule } from '../form-directives/form-directives.module'
import { SourceHitComponent } from './modals/source-hit/source-hit.component'
import { VisibilitySelectorModule } from '../visibility-selector/visibility-selector.module'
+import { AlertMessageModule } from '../alert-message/alert-message.module'
@NgModule({
declarations: [
@@ -38,6 +39,7 @@ import { VisibilitySelectorModule } from '../visibility-selector/visibility-sele
PanelModule,
SharedModule,
ModalModule,
+ AlertMessageModule,
MatDialogModule,
MatButtonModule,
MatInputModule,
diff --git a/src/app/cdk/side-bar/side-bar/side-bar.component.html b/src/app/cdk/side-bar/side-bar/side-bar.component.html
index 1df11041f6..1da483eed4 100644
--- a/src/app/cdk/side-bar/side-bar/side-bar.component.html
+++ b/src/app/cdk/side-bar/side-bar/side-bar.component.html
@@ -52,7 +52,9 @@ Emails
0">
{{ email.value }}
diff --git a/src/app/cdk/visibility-selector/visibility-selector/visibility-selector.component.html b/src/app/cdk/visibility-selector/visibility-selector/visibility-selector.component.html
index e19d916266..963db079c4 100644
--- a/src/app/cdk/visibility-selector/visibility-selector/visibility-selector.component.html
+++ b/src/app/cdk/visibility-selector/visibility-selector/visibility-selector.component.html
@@ -1,6 +1,7 @@
-
+
+
-
this._errorHandler.handleError(error)),
catchError((error) => of({ emails: [] })),
map((value: EmailsEndpoint) => {
- value.emails
- .sort(this.sortByEmailByValue)
- .sort(this.sortByEmailByVerifiedState)
- .sort(this.sortByEmailPrimaryState)
+ value.emails.sort(this.sortByEmailCreationDate)
return value
}),
tap((value) => {
@@ -209,4 +206,19 @@ export class RecordEmailsService {
): number {
return a.primary === b.primary ? 0 : a.primary ? -1 : 1
}
+
+ sortByEmailCreationDate(
+ a: AssertionVisibilityString,
+ b: AssertionVisibilityString
+ ): number {
+ const dateA = Date.parse(
+ `${a.createdDate.year}-${a.createdDate.month}-${a.createdDate.day}`
+ )
+
+ const dateB = Date.parse(
+ `${b.createdDate.year}-${b.createdDate.month}-${b.createdDate.day}`
+ )
+
+ return dateA - dateB
+ }
}
diff --git a/src/locale/properties/side-bar/side-bar.en.properties b/src/locale/properties/side-bar/side-bar.en.properties
index ce62aade45..20f1c7d63e 100644
--- a/src/locale/properties/side-bar/side-bar.en.properties
+++ b/src/locale/properties/side-bar/side-bar.en.properties
@@ -3,10 +3,18 @@ side-bar.OrcidWorkBest=ORCID works best when you have multiple email addresses.
side-bar.termOfUse=ORCID terms of use
side-bar.youMayOnly=you may only add email addresses that you have control over. Each time you add an email address we will send you an email asking you to verify it.
side-bar.primaryEmail=Primary email address
+side-bar.verifiedEmail=Verified email address
side-bar.emailCanNotBeDuplicated=Email can not be duplicated
side-bar.noOtherEmails=You haven’t added any other email addresses yet.
side-bar.invalidEmailFormat=Invalid email format
side-bar.pleaseVerify=Please verify your primary email address!
+side-bar.pleaseVerifyWarning=Please verify your email addresses
+side-bar.verifyToAccessOrcidFeatures=To access all of ORCID’s editing features you must verify at least one email address. Until then you will only be able to manage
+side-bar.names=names
+side-bar.and=and
+side-bar.emailAddresses=email addresses
+side-bar.emailAddressesUppercase=Email addresses
+side-bar.inYourOrcidRecord=in your ORCID record.
side-bar.youNeedToVerify=You need to verify your primary email in order to access all of ORCID’s editing features.
side-bar.youNeedToVerify2=To verify your email, click the link in the message sent to:
side-bar.needHelp=Need help?
@@ -19,9 +27,11 @@ side-bar.alreadyAssociated=This email is already associated with an ORCID record
side-bar.additionalEmailsDuplicate=Additional emails cannot be duplicated
side-bar.makePrimary=Make primary email
side-bar.resendVerification=Resend verification email
+side-bar.verificationEmailSent=Verification email sent
side-bar.pleaseCheckYour=Please check your email inbox (or maybe your spam folder) for an email with a link to complete the process.
side-bar.otherEmail=Add other email address
side-bar.anotherEmail=Add another email address
+side-bar.havingMultipleEmails=Having multiple email addresses helps you maintain access to your ORCID record. A mix of personal and professional email addresses works best.
side-bar.perOrcid=Per the
side-bar.personalIdentifiers=Other IDs
side-bar.myOtherIdentifiers=My other identifiers
@@ -35,6 +45,11 @@ side-bar.myCountriesAndLocations=My countries/locations
side-bar.addCountryOrLocation=Add a country or location
side-bar.addAnotherCountryOrLocation=Add another country or location
side-bar.countriesOrLocationsDescription=Add countries or locations to your ORCID record to highlight where you conduct your research or where your research is focused. You can add as many countries or locations as you want.
+side-bar.emailNotifications=Email notifications
+side-bar.whichVerifiedEmail=Which verified email address should we send your ORCID notifications to? You can change the frequency of these notification emails in
+side-bar.yourOrcidAccountSettings=your ORCID account settings.
+side-bar.deleteTooltip=You can't delete the only email address in your account
+side-bar.visibilityTooltip=Visibility set to Only me
side-bar.ariaLabelOrcidTermsOfUseBase=ORCID knowledge base (Opens in a new tab)
side-bar.ariaLabelOrcidTermsSupport=ORCID support page (Opens in a new tab)
side-bar.ariaLabelOrcidTermsOfUseLink=ORCID terms of use (Opens in a new tab)
@@ -74,3 +89,6 @@ side-bar.ariaLabelPrimaryEmailPrivate=Set primary email visibility to Only Me
side-bar.ariaLabelOtherEmailPublic=Set other email visibility to Everyone
side-bar.ariaLabelOtherEmailTrustedParties=Set other email visibility to Trusted Parties
side-bar.ariaLabelOtherEmailPrivate=Set other email visibility to Only Me
+side-bar.ariaLabelEmailPublic=Set email visibility to Everyone
+side-bar.ariaLabelEmailTrustedParties=Set email visibility to Trusted Parties
+side-bar.ariaLabelEmailPrivate=Set email visibility to Only Me