Bladeren bron

Rearrange layout to have the new affiliation form within the affiliations table.

Paulo Reis 8 jaren geleden
bovenliggende
commit
62ab9dbb98

+ 151 - 125
services/web/app/views/user/settings.pug

@@ -14,6 +14,156 @@ block content
 									|  #{translate("thanks_settings_updated")}
 							form-messages(for="changePasswordForm")
 							.container-fluid
+								form.row(
+									ng-controller="UserAffiliationsController"
+									name="affiliationsForm"
+								)
+									.col-md-12
+										h3 Emails and Affiliations
+										p.small Add additional email addresses to your account to access any upgrades your university or institution has, to make it easier for collaborators to find you, and to make sure you can recover your account.
+
+										table.table.affiliations-table
+											thead
+												tr
+													th.affiliations-table-email Email
+													th.affiliations-table-institution Institution and role
+													th.affiliations-table-inline-actions
+											tbody
+												tr(
+													ng-repeat="userEmail in userEmails"
+												)
+													td {{ userEmail.email + (userEmail.default ? ' (default)' : '') }}
+													td {{ userEmail.institution }}
+													td 
+														a(
+															href
+															ng-if="!userEmail.default"
+															ng-click="setDefaultUserEmail(userEmail.email)"
+														) Make default
+														br
+														a(
+															href
+															ng-if="!userEmail.default"
+															ng-click="removeUserEmail(userEmail.email)"
+														) Remove
+												tr(
+													ng-if="ui.isLoadingEmails"
+												)
+													td.text-center(colspan="3") 
+														i.fa.fa-fw.fa-spin.fa-refresh
+														|  Loading...
+												
+												tr(
+													ng-if="!ui.showAddEmailUI && !ui.isLoadingEmails"
+												)
+													td(colspan="3")
+														a(
+															href
+															ng-click="showAddEmailForm()"
+														) Add new email
+
+												tr(
+													ng-if="ui.showAddEmailUI"
+												)
+													td
+														p
+															input-suggestions(
+																ng-model="newAffiliation.email"
+																ng-model-options="{ allowInvalid: true }"
+																get-suggestion="getEmailSuggestion(userInput)"
+																on-blur="handleEmailInputBlur()"
+																input-id="affilitations-email"
+																input-name="affilitationsEmail"
+																input-placeholder="e.g. johndoe@mit.edu"
+																input-type="email"
+																input-required="true"
+															)
+													td
+														p(
+															ng-if="newAffiliation.university && !ui.showManualUniversitySelectionUI"
+														)
+															| {{ newAffiliation.university.name }} (
+															a(
+																href
+																ng-click="selectUniversityManually();"
+															) change
+															| )
+														p(
+															ng-if="!newAffiliation.university && !ui.isValidEmail && !ui.showManualUniversitySelectionUI"
+														) Start by adding your email address.
+														p(
+															ng-if="!newAffiliation.university && ui.isValidEmail && !ui.isBlacklistedEmail && !ui.showManualUniversitySelectionUI"
+														)
+															| Is your email affiliated with an institution? 
+															br
+															a(
+																href
+																ng-click="selectUniversityManually();"
+															) Let us know
+														div(
+															ng-if="ui.showManualUniversitySelectionUI"
+														)
+															p
+																ui-select(
+																	ng-model="newAffiliation.country"
+																)
+																	ui-select-match(
+																		placeholder="Select your country"
+																	) {{ $select.selected.name }}
+																	ui-select-choices(
+																		repeat="country in countries | filter: $select.search"
+																	)
+																		span(
+																			ng-bind="country.name"
+																		)
+															p
+																ui-select(
+																	ng-model="newAffiliation.university"
+																	ng-disabled="!newAffiliation.country"
+																	tagging="addUniversityToSelection"
+																	tagging-label="false"
+																)
+																	ui-select-match(
+																		placeholder="Select your university"
+																	) {{ $select.selected.name }}
+																	ui-select-choices(
+																		repeat="university in universities | filter: $select.search"
+																	)
+																		span(
+																			ng-bind="university.name"
+																		)
+														div(
+															ng-if="ui.isValidEmail && newAffiliation.university"
+														)
+															p
+																input.form-control(
+																	type="text"
+																	id="affiliations-role"
+																	placeholder="Role"
+																	ng-model="newAffiliation.role"
+																)
+															p
+																input.form-control(
+																	type="text"
+																	id="affiliations-department"
+																	placeholder="Department"
+																	ng-model="newAffiliation.department"
+																)
+													td
+														button.btn.btn-primary(
+															ng-disabled="affiliationsForm.$invalid || ui.isAddingNewEmail"
+															ng-click="addNewEmail()"
+														)
+															span(
+																ng-if="!ui.isAddingNewEmail"
+															) Add new email
+															span(
+																ng-if="ui.isAddingNewEmail"
+															)
+																i.fa.fa-fw.fa-spin.fa-refresh
+																|  Adding...
+										hr
+
 								.row
 									.col-md-5
 										h3  #{translate("update_account_info")}
@@ -116,131 +266,7 @@ block content
 														ng-disabled="changePasswordForm.$invalid"
 													) #{translate("change")}
 
-							hr
-							form(
-								ng-controller="UserAffiliationsController"
-								novalidate
-								name="affiliationsForm"
-							)
-								h3 Emails and affiliations
-								p Do you use multiple e-mail addresses? If so, add those here.
-								ul
-									li You'll retain access to your account even if you lose access to one of your emails
-									li Others users will be able to find you under different email addresses when sharing projects
-									li If your e-mail is affiliated with an institution with a group license, your account will be associated with that institution (and you'll gain acess to any benefits the institution may have).
-
-								.affiliations-row
-									.affiliation-col-4
-										label(for="affiliations-email") #{translate("email")}
-										input-suggestions(
-											ng-model="newAffiliation.email"
-											ng-model-options="{ allowInvalid: true }"
-											get-suggestion="getEmailSuggestion(userInput)"
-											on-blur="handleEmailInputBlur()"
-											input-id="affilitations-email"
-											input-name="affilitationsEmail"
-											input-placeholder="e.g. johndoe@mit.edu"
-											input-type="email"
-											input-required="true"
-										)
-									.affiliation-col-8
-										p.affiliation-input-feedback(
-											ng-if="newAffiliation.university && !showManualUniversitySelectionUI"
-										)
-											| {{ newAffiliation.university.name }} (
-											a(
-												href
-												ng-click="selectUniversityManually();"
-											) change
-											| )
-										p.affiliation-input-feedback(
-											ng-if="!newAffiliation.university && !isValidEmail && !showManualUniversitySelectionUI"
-										) Start by adding your email address.
-										p.affiliation-input-feedback(
-											ng-if="!newAffiliation.university && isValidEmail && !isBlacklistedEmail && !showManualUniversitySelectionUI"
-										)
-											| Is your email affiliated with an institution? 
-											a(
-												href
-												ng-click="selectUniversityManually();"
-											) Let us know
-								.affiliations-row(
-									ng-if="isValidEmail && showManualUniversitySelectionUI"
-								)
-									.affiliation-col-4
-										label Institution
-										ui-select(
-											ng-model="newAffiliation.country"
-										)
-											ui-select-match(
-												placeholder="Select your country"
-											) {{ $select.selected.name }}
-											ui-select-choices(
-												repeat="country in countries | filter: $select.search"
-											)
-												span(
-													ng-bind="country.name"
-												)
-									.affiliation-col-4
-										ui-select(
-											ng-model="newAffiliation.university"
-											ng-disabled="!newAffiliation.country"
-											tagging="addUniversityToSelection"
-											tagging-label="false"
-										)
-											ui-select-match(
-												placeholder="Select your university"
-											) {{ $select.selected.name }}
-											ui-select-choices(
-												repeat="university in universities | filter: $select.search"
-											)
-												span(
-													ng-bind="university.name"
-												)
-								.affiliations-row(
-									ng-if="isValidEmail && newAffiliation.university"
-								)
-									.affiliation-col-4
-										label(for="affiliations-role") Role
-										input.form-control(
-											type="text"
-											id="affiliations-role"
-											placeholder="e.g. Professor"
-											ng-model="newAffiliation.role"
-										)
-									.affiliation-col-4
-										label(for="affiliations-department") Department
-										input.form-control(
-											type="text"
-											id="affiliations-department"
-											placeholder="e.g. Mathematics"
-											ng-model="newAffiliation.department"
-										)
-								.affiliations-row
-									.affiliation-col-4
-										input.btn.btn-primary(
-											type="submit"
-											ng-disabled="affiliationsForm.$invalid"
-											ng-click="handleAffiliationFormSubmit()"
-											value="Add new email"
-										)
-
-								//- p Your current affiliations
-
-								table.table
-									thead
-										tr
-											th Email
-											th Institution and role
-											th
-									tbody
-										tr(
-											ng-repeat="userEmail in userEmails"
-										)
-											td {{ userEmail.email + (userEmail.default ? ' (default)' : '') }}
-											td {{ userEmail.institution }}
-											td Remove
-
+							
 
 							| !{moduleIncludes("userSettings", locals)}
 

+ 47 - 21
services/web/public/coffee/main/affiliations/controllers/UserAffiliationsController.coffee

@@ -5,18 +5,9 @@ define [
 		$scope.userEmails = []
 		$scope.countries = []
 		$scope.universities = []
-		$scope.newAffiliation =
-			email: ""
-			country: null
-			university: null
-			role: null
-			department: null
-		$scope.showManualUniversitySelectionUI = false
-		$scope.isValidEmail = false
-		$scope.isBlacklistedEmail = false
 
 		LOCAL_AND_DOMAIN_REGEX = /([^@]+)@(.+)/
-		EMAIL_REGEX = /^([A-Za-z0-9_\-\.]+)@([^\.]+)\.([A-Za-z]+)$/
+		EMAIL_REGEX = /^([A-Za-z0-9_\-\.]+)@([^\.]+)\.([A-Za-z0-9_\-\.]+)([^\.])$/
 
 		_matchLocalAndDomain = (userEmailInput) ->
 			match = userEmailInput?.match LOCAL_AND_DOMAIN_REGEX
@@ -30,14 +21,14 @@ define [
 
 		$scope.getEmailSuggestion = (userInput) ->
 			userInputLocalAndDomain = _matchLocalAndDomain(userInput)
-			$scope.isValidEmail = EMAIL_REGEX.test userInput  
-			$scope.isBlacklistedEmail = false
+			$scope.ui.isValidEmail = EMAIL_REGEX.test userInput
+			$scope.ui.isBlacklistedEmail = false
+			$scope.ui.showManualUniversitySelectionUI = false
 			if userInputLocalAndDomain.domain?
-				$scope.isBlacklistedEmail = UserAffiliationsDataService.isDomainBlacklisted userInputLocalAndDomain.domain
+				$scope.ui.isBlacklistedEmail = UserAffiliationsDataService.isDomainBlacklisted userInputLocalAndDomain.domain
 
 				UserAffiliationsDataService.getUniversityDomainFromPartialDomainInput(userInputLocalAndDomain.domain)
 					.then (universityDomain) -> 						
-						$scope.showManualUniversitySelectionUI = false
 						if userInputLocalAndDomain.domain == universityDomain.hostname
 							$scope.newAffiliation.university = universityDomain.university
 							$scope.newAffiliation.department = universityDomain.department
@@ -61,9 +52,13 @@ define [
 		$scope.selectUniversityManually = () ->
 			$scope.newAffiliation.university = null
 			$scope.newAffiliation.department = null
-			$scope.showManualUniversitySelectionUI = true
+			$scope.ui.showManualUniversitySelectionUI = true
 
-		$scope.handleAffiliationFormSubmit = () ->
+		$scope.showAddEmailForm = () ->
+			$scope.ui.showAddEmailUI = true
+
+		$scope.addNewEmail = () ->
+			$scope.ui.isAddingNewEmail = true
 			if !$scope.newAffiliation.university?
 				addEmailPromise = UserAffiliationsDataService
 					.addUserEmail $scope.newAffiliation.email
@@ -85,14 +80,45 @@ define [
 							$scope.newAffiliation.role,
 							$scope.newAffiliation.department
 						)
-			addEmailPromise.then () -> getUserEmails()
-			
+			addEmailPromise.then () -> 
+				_reset()
+				_getUserEmails()
+
+		$scope.setDefaultUserEmail = (email) ->
+			UserAffiliationsDataService
+				.setDefaultUserEmail email
+				.then () -> _getUserEmails()
+
+		$scope.removeUserEmail = (email) ->
+			UserAffiliationsDataService
+				.removeUserEmail email
+				.then () -> _getUserEmails()
+
+		_reset = () ->
+			$scope.newAffiliation =
+				email: ""
+				country: null
+				university: null
+				role: null
+				department: null
+			$scope.ui = 
+				showManualUniversitySelectionUI: false
+				isLoadingEmails: false
+				isAddingNewEmail: false
+				showAddEmailUI: false
+				isValidEmail: false
+				isBlacklistedEmail: false
+		_reset()
+
 		# Populates the emails table
-		getUserEmails = () ->
+		_getUserEmails = () ->
+			$scope.ui.isLoadingEmails = true
 			UserAffiliationsDataService
 				.getUserEmails() 
-				.then (emails) -> $scope.userEmails = emails
-		getUserEmails()
+				.then (emails) -> 
+					$scope.userEmails = emails
+					$scope.ui.isLoadingEmails = false
+		_getUserEmails()
 
 		# Populates the countries dropdown
 		UserAffiliationsDataService

+ 14 - 0
services/web/public/coffee/main/affiliations/factories/UserAffiliationsDataService.coffee

@@ -72,6 +72,18 @@ define [
 				_csrf: window.csrfToken
 			}
 
+		setDefaultUserEmail = (email) ->
+			$http.post "/user/emails/default", {
+				email,
+				_csrf: window.csrfToken
+			}
+
+		removeUserEmail = (email) ->
+			$http.delete "/user/emails/#{ encodeURIComponent(email) }", {
+				headers: 
+					"X-CSRF-Token": window.csrfToken
+			}
+
 		isDomainBlacklisted = (domain) ->
 			domain.toLowerCase() of domainsBlackList
 
@@ -83,6 +95,8 @@ define [
 			addUserEmail
 			addUserAffiliationWithUnknownUniversity
 			addUserAffiliation
+			setDefaultUserEmail
+			removeUserEmail
 			isDomainBlacklisted
 		}
 	]

+ 9 - 39
services/web/public/stylesheets/app/account-settings.less

@@ -11,46 +11,16 @@
 	}
 }
 
-
-.affiliations-row {
-	display: flex;
-	margin-left: -(@grid-gutter-width / 2);
-	margin-right: -(@grid-gutter-width / 2);
-	@media (min-width: @screen-sm-min) {
-		align-items: flex-end;
-	}
+.affiliations-table {
+	table-layout: fixed;
 }
-	.affiliation-col-4,
-	.affiliation-col-8 {
-		width: 100%;
-		flex-grow: 0;
-		flex-shrink: 0;
-		padding-left: (@grid-gutter-width / 2);
-		padding-right: (@grid-gutter-width / 2);
-		margin-bottom: (@grid-gutter-width / 2);
-	}
-
-	.affiliation-col-4 {
-		@media (min-width: @screen-sm-min) {
-			width: (4 / 12) * 100%;
-		}
+	.affiliations-table-email {
+		width: 40%;
 	}
-	
-	.affiliation-col-8 {
-		@media (min-width: @screen-sm-min) {
-			width: (8 / 12) * 100%;
-		}
+	.affiliations-table-institution {
+		width: 40%;
 	}
-
-	.affiliation-col-align-right {
-		@media (min-width: @screen-sm-min) {
-			display: flex;
-			justify-content: flex-end;
-		}
+	.affiliations-table-inline-actions {
+		width: 20%;
 	}
-
-	.affiliation-input-feedback {
-		height: @input-height-base;
-		padding: @padding-base-vertical;
-		margin: 0;
-	}
+