mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Merge pull request #3581 from overleaf/jel-dash-consolidate-emails-requests
Consolidate emails requests on the dashboard GitOrigin-RevId: acfaf92dee257712e1eb3ffbf75b536fd1619e1d
This commit is contained in:
parent
2c200d9e76
commit
2dd860c431
9 changed files with 67 additions and 83 deletions
|
@ -33,7 +33,6 @@ const NotificationsBuilder = require('../Notifications/NotificationsBuilder')
|
||||||
const { V1ConnectionError } = require('../Errors/Errors')
|
const { V1ConnectionError } = require('../Errors/Errors')
|
||||||
const Features = require('../../infrastructure/Features')
|
const Features = require('../../infrastructure/Features')
|
||||||
const BrandVariationsHandler = require('../BrandVariations/BrandVariationsHandler')
|
const BrandVariationsHandler = require('../BrandVariations/BrandVariationsHandler')
|
||||||
const { getUserAffiliations } = require('../Institutions/InstitutionsAPI')
|
|
||||||
const UserController = require('../User/UserController')
|
const UserController = require('../User/UserController')
|
||||||
const AnalyticsManager = require('../Analytics/AnalyticsManager')
|
const AnalyticsManager = require('../Analytics/AnalyticsManager')
|
||||||
const Modules = require('../../infrastructure/Modules')
|
const Modules = require('../../infrastructure/Modules')
|
||||||
|
@ -416,18 +415,6 @@ const ProjectController = {
|
||||||
cb
|
cb
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
userAffiliations(cb) {
|
|
||||||
if (!Features.hasFeature('affiliations')) {
|
|
||||||
return cb(null, [])
|
|
||||||
}
|
|
||||||
getUserAffiliations(userId, (error, affiliations) => {
|
|
||||||
if (error && error instanceof V1ConnectionError) {
|
|
||||||
noV1Connection = true
|
|
||||||
return cb(null, [])
|
|
||||||
}
|
|
||||||
cb(error, affiliations)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
userEmailsData(cb) {
|
userEmailsData(cb) {
|
||||||
const result = { list: [], allInReconfirmNotificationPeriods: [] }
|
const result = { list: [], allInReconfirmNotificationPeriods: [] }
|
||||||
|
|
||||||
|
@ -463,12 +450,17 @@ const ProjectController = {
|
||||||
OError.tag(err, 'error getting data for project list page')
|
OError.tag(err, 'error getting data for project list page')
|
||||||
return next(err)
|
return next(err)
|
||||||
}
|
}
|
||||||
const {
|
const { notifications, user, userEmailsData } = results
|
||||||
notifications,
|
|
||||||
user,
|
const userEmails = userEmailsData.list || []
|
||||||
userAffiliations,
|
|
||||||
userEmailsData
|
const userAffiliations = userEmails
|
||||||
} = results
|
.filter(emailData => !!emailData.affiliation)
|
||||||
|
.map(emailData => {
|
||||||
|
const result = emailData.affiliation
|
||||||
|
result.email = emailData.email
|
||||||
|
return result
|
||||||
|
})
|
||||||
|
|
||||||
const { allInReconfirmNotificationPeriods } = userEmailsData
|
const { allInReconfirmNotificationPeriods } = userEmailsData
|
||||||
|
|
||||||
|
@ -600,6 +592,7 @@ const ProjectController = {
|
||||||
portalTemplates,
|
portalTemplates,
|
||||||
user,
|
user,
|
||||||
userAffiliations,
|
userAffiliations,
|
||||||
|
userEmails,
|
||||||
hasSubscription: results.hasSubscription,
|
hasSubscription: results.hasSubscription,
|
||||||
institutionLinkingError,
|
institutionLinkingError,
|
||||||
warnings,
|
warnings,
|
||||||
|
|
|
@ -194,7 +194,14 @@ var decorateFullEmails = (
|
||||||
aff => aff.email === emailData.email
|
aff => aff.email === emailData.email
|
||||||
)
|
)
|
||||||
if (affiliation) {
|
if (affiliation) {
|
||||||
const { institution, inferred, role, department, licence } = affiliation
|
const {
|
||||||
|
institution,
|
||||||
|
inferred,
|
||||||
|
role,
|
||||||
|
department,
|
||||||
|
licence,
|
||||||
|
portal
|
||||||
|
} = affiliation
|
||||||
const inReconfirmNotificationPeriod = _emailInReconfirmNotificationPeriod(
|
const inReconfirmNotificationPeriod = _emailInReconfirmNotificationPeriod(
|
||||||
emailData,
|
emailData,
|
||||||
institution
|
institution
|
||||||
|
@ -205,7 +212,8 @@ var decorateFullEmails = (
|
||||||
inReconfirmNotificationPeriod,
|
inReconfirmNotificationPeriod,
|
||||||
role,
|
role,
|
||||||
department,
|
department,
|
||||||
licence
|
licence,
|
||||||
|
portal
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ block vars
|
||||||
|
|
||||||
block content
|
block content
|
||||||
script#data(type="application/json").
|
script#data(type="application/json").
|
||||||
!{StringHelper.stringifyJsonForScript({ projects, tags, notifications, notificationsInstitution })}
|
!{StringHelper.stringifyJsonForScript({ projects, tags, notifications, notificationsInstitution, userAffiliations, userEmails })}
|
||||||
|
|
||||||
script(type="text/javascript").
|
script(type="text/javascript").
|
||||||
window.data = JSON.parse(document.querySelector("#data").text);
|
window.data = JSON.parse(document.querySelector("#data").text);
|
||||||
|
|
|
@ -139,7 +139,7 @@
|
||||||
span(ng-controller="LeftHandMenuPromoController", ng-cloak)
|
span(ng-controller="LeftHandMenuPromoController", ng-cloak)
|
||||||
|
|
||||||
.row-spaced#userProfileInformation(ng-if="hasProjects")
|
.row-spaced#userProfileInformation(ng-if="hasProjects")
|
||||||
div(ng-show="userEmails.length > 0 && userAffiliations.length == 0", ng-cloak)
|
div(ng-hide="withAffiliations", ng-cloak)
|
||||||
hr
|
hr
|
||||||
.text-centered.user-profile
|
.text-centered.user-profile
|
||||||
p Are you affiliated with an institution?
|
p Are you affiliated with an institution?
|
||||||
|
|
|
@ -17,17 +17,10 @@ export default App.controller('LeftHandMenuPromoController', function(
|
||||||
}
|
}
|
||||||
|
|
||||||
const _userHasNoAffiliation = function() {
|
const _userHasNoAffiliation = function() {
|
||||||
$scope.userEmails = []
|
$scope.withAffiliations = window.data.userAffiliations.length > 0
|
||||||
$scope.userAffiliations = []
|
$scope.userOnPayingUniversity = window.data.userAffiliations.some(
|
||||||
return UserAffiliationsDataService.getUserEmails().then(function(emails) {
|
affiliation => affiliation.licence && affiliation.licence !== 'free'
|
||||||
$scope.userEmails = emails
|
)
|
||||||
$scope.userAffiliations = emails
|
|
||||||
.filter(email => email.affiliation)
|
|
||||||
.map(email => email.affiliation)
|
|
||||||
$scope.userOnPayingUniversity = $scope.userAffiliations.some(
|
|
||||||
affiliation => affiliation.licence && affiliation.licence !== 'free'
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_userHasNoAffiliation()
|
_userHasNoAffiliation()
|
||||||
|
|
|
@ -74,7 +74,7 @@ App.controller('EmailNotificationController', function(
|
||||||
$http,
|
$http,
|
||||||
UserAffiliationsDataService
|
UserAffiliationsDataService
|
||||||
) {
|
) {
|
||||||
$scope.userEmails = []
|
$scope.userEmails = window.data.userEmails
|
||||||
const _ssoAvailable = email => {
|
const _ssoAvailable = email => {
|
||||||
if (!ExposedSettings.hasSamlFeature) return false
|
if (!ExposedSettings.hasSamlFeature) return false
|
||||||
if (email.samlProviderId) return true
|
if (email.samlProviderId) return true
|
||||||
|
@ -101,13 +101,6 @@ App.controller('EmailNotificationController', function(
|
||||||
userEmail.hide = false
|
userEmail.hide = false
|
||||||
}
|
}
|
||||||
|
|
||||||
const _getUserEmails = () =>
|
|
||||||
UserAffiliationsDataService.getUserEmails().then(function(emails) {
|
|
||||||
$scope.userEmails = emails
|
|
||||||
$scope.$emit('project-list:notifications-received')
|
|
||||||
})
|
|
||||||
_getUserEmails()
|
|
||||||
|
|
||||||
$scope.resendConfirmationEmail = function(userEmail) {
|
$scope.resendConfirmationEmail = function(userEmail) {
|
||||||
userEmail.confirmationInflight = true
|
userEmail.confirmationInflight = true
|
||||||
userEmail.error = false
|
userEmail.error = false
|
||||||
|
|
|
@ -520,7 +520,8 @@ describe('Subscriptions', function() {
|
||||||
institution: {
|
institution: {
|
||||||
name: 'Stanford',
|
name: 'Stanford',
|
||||||
confirmed: true
|
confirmed: true
|
||||||
}
|
},
|
||||||
|
portal: undefined
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
})
|
})
|
||||||
|
|
|
@ -114,18 +114,6 @@ describe('ProjectController', function() {
|
||||||
this.TpdsProjectFlusher = {
|
this.TpdsProjectFlusher = {
|
||||||
flushProjectToTpdsIfNeeded: sinon.stub().yields()
|
flushProjectToTpdsIfNeeded: sinon.stub().yields()
|
||||||
}
|
}
|
||||||
this.getUserAffiliations = sinon.stub().callsArgWith(1, null, [
|
|
||||||
{
|
|
||||||
email: 'test@overleaf.com',
|
|
||||||
institution: {
|
|
||||||
id: 1,
|
|
||||||
confirmed: true,
|
|
||||||
name: 'Overleaf',
|
|
||||||
ssoBeta: false,
|
|
||||||
ssoEnabled: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
])
|
|
||||||
this.Metrics = {
|
this.Metrics = {
|
||||||
Timer: class {
|
Timer: class {
|
||||||
done() {}
|
done() {}
|
||||||
|
@ -173,9 +161,6 @@ describe('ProjectController', function() {
|
||||||
'../User/UserGetter': this.UserGetter,
|
'../User/UserGetter': this.UserGetter,
|
||||||
'../BrandVariations/BrandVariationsHandler': this
|
'../BrandVariations/BrandVariationsHandler': this
|
||||||
.BrandVariationsHandler,
|
.BrandVariationsHandler,
|
||||||
'../Institutions/InstitutionsAPI': {
|
|
||||||
getUserAffiliations: this.getUserAffiliations
|
|
||||||
},
|
|
||||||
'../ThirdPartyDataStore/TpdsProjectFlusher': this.TpdsProjectFlusher,
|
'../ThirdPartyDataStore/TpdsProjectFlusher': this.TpdsProjectFlusher,
|
||||||
'../../models/Project': {},
|
'../../models/Project': {},
|
||||||
'../Analytics/AnalyticsManager': { recordEvent: () => {} },
|
'../Analytics/AnalyticsManager': { recordEvent: () => {} },
|
||||||
|
@ -526,15 +511,6 @@ describe('ProjectController', function() {
|
||||||
this.ProjectController.projectListPage(this.req, this.res)
|
this.ProjectController.projectListPage(this.req, this.res)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should show a warning when there is an error getting affiliations from v1', function(done) {
|
|
||||||
this.getUserAffiliations.yields(new Errors.V1ConnectionError('error'))
|
|
||||||
this.res.render = (pageName, opts) => {
|
|
||||||
expect(opts.warnings).to.contain(this.connectionWarning)
|
|
||||||
done()
|
|
||||||
}
|
|
||||||
this.ProjectController.projectListPage(this.req, this.res)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should show a warning when there is an error getting full emails due to v1', function(done) {
|
it('should show a warning when there is an error getting full emails due to v1', function(done) {
|
||||||
this.UserGetter.getUserFullEmails.yields(
|
this.UserGetter.getUserFullEmails.yields(
|
||||||
new Errors.V1ConnectionError('error')
|
new Errors.V1ConnectionError('error')
|
||||||
|
@ -597,6 +573,20 @@ describe('ProjectController', function() {
|
||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
it('should show institution SSO available notification for confirmed domains', function() {
|
it('should show institution SSO available notification for confirmed domains', function() {
|
||||||
|
this.UserGetter.getUserFullEmails.yields(null, [
|
||||||
|
{
|
||||||
|
email: 'test@overleaf.com',
|
||||||
|
affiliation: {
|
||||||
|
institution: {
|
||||||
|
id: 1,
|
||||||
|
confirmed: true,
|
||||||
|
name: 'Overleaf',
|
||||||
|
ssoBeta: false,
|
||||||
|
ssoEnabled: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
])
|
||||||
this.res.render = (pageName, opts) => {
|
this.res.render = (pageName, opts) => {
|
||||||
expect(opts.notificationsInstitution).to.deep.include({
|
expect(opts.notificationsInstitution).to.deep.include({
|
||||||
email: this.institutionEmail,
|
email: this.institutionEmail,
|
||||||
|
@ -713,15 +703,17 @@ describe('ProjectController', function() {
|
||||||
})
|
})
|
||||||
describe('for an unconfirmed domain for an SSO institution', function() {
|
describe('for an unconfirmed domain for an SSO institution', function() {
|
||||||
beforeEach(function(done) {
|
beforeEach(function(done) {
|
||||||
this.getUserAffiliations.yields(null, [
|
this.UserGetter.getUserFullEmails.yields(null, [
|
||||||
{
|
{
|
||||||
email: 'test@overleaf-uncofirmed.com',
|
email: 'test@overleaf-uncofirmed.com',
|
||||||
institution: {
|
affiliation: {
|
||||||
id: 1,
|
institution: {
|
||||||
confirmed: false,
|
id: 1,
|
||||||
name: 'Overleaf',
|
confirmed: false,
|
||||||
ssoBeta: false,
|
name: 'Overleaf',
|
||||||
ssoEnabled: true
|
ssoBeta: false,
|
||||||
|
ssoEnabled: true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
@ -758,15 +750,17 @@ describe('ProjectController', function() {
|
||||||
})
|
})
|
||||||
describe('Institution with SSO beta testable', function() {
|
describe('Institution with SSO beta testable', function() {
|
||||||
beforeEach(function(done) {
|
beforeEach(function(done) {
|
||||||
this.getUserAffiliations.yields(null, [
|
this.UserGetter.getUserFullEmails.yields(null, [
|
||||||
{
|
{
|
||||||
email: 'beta@beta.com',
|
email: 'beta@beta.com',
|
||||||
institution: {
|
affiliation: {
|
||||||
id: 2,
|
institution: {
|
||||||
confirmed: true,
|
id: 2,
|
||||||
name: 'Beta University',
|
confirmed: true,
|
||||||
ssoBeta: true,
|
name: 'Beta University',
|
||||||
ssoEnabled: false
|
ssoBeta: true,
|
||||||
|
ssoEnabled: false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
|
|
@ -174,7 +174,8 @@ describe('UserGetter', function() {
|
||||||
name: 'University Name',
|
name: 'University Name',
|
||||||
isUniversity: true,
|
isUniversity: true,
|
||||||
confirmed: true
|
confirmed: true
|
||||||
}
|
},
|
||||||
|
portal: undefined
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
this.getUserAffiliations.resolves(affiliationsData)
|
this.getUserAffiliations.resolves(affiliationsData)
|
||||||
|
@ -195,7 +196,8 @@ describe('UserGetter', function() {
|
||||||
department: affiliationsData[0].department,
|
department: affiliationsData[0].department,
|
||||||
role: affiliationsData[0].role,
|
role: affiliationsData[0].role,
|
||||||
licence: affiliationsData[0].licence,
|
licence: affiliationsData[0].licence,
|
||||||
inReconfirmNotificationPeriod: false
|
inReconfirmNotificationPeriod: false,
|
||||||
|
portal: undefined
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue