Merge pull request #3095 from overleaf/hb-last-login-date-groups-csv

Last login date for groups csv

GitOrigin-RevId: c615db3086ec84f2a33710fc0117d711862b6f6c
This commit is contained in:
Timothée Alby 2020-08-12 16:19:14 +02:00 committed by Copybot
parent d932c153c0
commit 0cec198a08
5 changed files with 37 additions and 17 deletions

View file

@ -1,6 +1,6 @@
/* eslint-disable
max-len,
*/
max-len,
*/
// TODO: This file was created by bulk-decaffeinate.
// Fix any style issues and re-enable lint.
/*
@ -14,6 +14,7 @@ const AuthenticationController = require('../Authentication/AuthenticationContro
const UserMembershipHandler = require('./UserMembershipHandler')
const Errors = require('../Errors/Errors')
const EmailHelper = require('../Helpers/EmailHelper')
const CSVParser = require('json2csv').Parser
module.exports = {
index(req, res, next) {
@ -133,6 +134,7 @@ module.exports = {
exportCsv(req, res, next) {
const { entity, entityConfig } = req
const fields = ['email', 'last_logged_in_at']
return UserMembershipHandler.getUsers(entity, entityConfig, function(
error,
@ -141,13 +143,10 @@ module.exports = {
if (error != null) {
return next(error)
}
let csvOutput = ''
for (let user of Array.from(users)) {
csvOutput += user.email + '\n'
}
const csvParser = new CSVParser({ fields })
res.header('Content-Disposition', 'attachment; filename=Group.csv')
res.contentType('text/csv')
return res.send(csvOutput)
return res.send(csvParser.parse(users))
})
},

View file

@ -33,7 +33,12 @@ module.exports = UserMembershipViewModel = {
}
const userId = userOrIdOrEmail
const projection = { email: 1, first_name: 1, last_name: 1 }
const projection = {
email: 1,
first_name: 1,
last_name: 1,
lastLoggedIn: 1
}
return UserGetter.getUser(userId, projection, function(error, user) {
if (error != null || user == null) {
return callback(null, buildUserViewModelWithId(userId.toString()))
@ -52,6 +57,7 @@ var buildUserViewModel = function(user, isInvite) {
email: user.email || null,
first_name: user.first_name || null,
last_name: user.last_name || null,
last_logged_in_at: user.lastLoggedIn || null,
invite: isInvite
}
}

View file

@ -30,14 +30,16 @@ block content
)
li.container-fluid
.row
.col-md-5
.col-md-4
input.select-all(
select-all,
type="checkbox"
)
span.header #{translate("email")}
.col-md-5
.col-md-4
span.header #{translate("name")}
.col-md-2
span.header #{translate("last_login")}
.col-md-2
span.header #{translate("accepted_invite")}
li.container-fluid(
@ -45,15 +47,17 @@ block content
ng-controller="UserMembershipListItemController"
)
.row
.col-md-5
.col-md-4
input.select-item(
select-individual,
type="checkbox",
ng-model="user.selected"
)
span.email {{ user.email }}
.col-md-5
.col-md-4
span.name {{ user.first_name }} {{ user.last_name }}
.col-md-2
span.lastLogin {{ user.last_logged_in_at | formatDate:'Do MMM YYYY' }}
.col-md-2
span.registered
i.fa.fa-check.text-success(ng-show="!user.invite" aria-hidden="true")
@ -102,7 +106,7 @@ block content
.row
.col-xs-2.col-xs-offset-10(ng-if="paths.exportMembers", ng-cloak)
a(href=paths.exportMembers) #{translate('export_csv')}
script(type="text/javascript").
window.users = !{StringHelper.stringifyJsonForScript(users)};

View file

@ -45,8 +45,16 @@ describe('UserMembershipController', function() {
}
}
this.users = [
{ _id: 'mock-member-id-1', email: 'mock-email-1@foo.com' },
{ _id: 'mock-member-id-2', email: 'mock-email-2@foo.com' }
{
_id: 'mock-member-id-1',
email: 'mock-email-1@foo.com',
last_logged_in_at: '2020-08-09T12:43:11.467Z'
},
{
_id: 'mock-member-id-2',
email: 'mock-email-2@foo.com',
last_logged_in_at: '2020-05-20T10:41:11.407Z'
}
]
this.AuthenticationController = {
@ -311,7 +319,7 @@ describe('UserMembershipController', function() {
it('should export the correct csv', function() {
return assertCalledWith(
this.res.send,
'mock-email-1@foo.com\nmock-email-2@foo.com\n'
'"email","last_logged_in_at"\n"mock-email-1@foo.com","2020-08-09T12:43:11.467Z"\n"mock-email-2@foo.com","2020-05-20T10:41:11.407Z"'
)
})
})

View file

@ -38,7 +38,8 @@ describe('UserMembershipViewModel', function() {
this.user = {
_id: 'mock-user-id',
email: 'mock-email@baz.com',
first_name: 'Name'
first_name: 'Name',
lastLoggedIn: '2020-05-20T10:41:11.407Z'
}
})
@ -48,6 +49,7 @@ describe('UserMembershipViewModel', function() {
return expect(viewModel).to.deep.equal({
email: this.email,
invite: true,
last_logged_in_at: null,
first_name: null,
last_name: null,
_id: null
@ -58,6 +60,7 @@ describe('UserMembershipViewModel', function() {
const viewModel = this.UserMembershipViewModel.build(this.user)
expect(viewModel._id).to.equal(this.user._id)
expect(viewModel.email).to.equal(this.user.email)
expect(viewModel.last_logged_in_at).to.equal(this.user.lastLoggedIn)
return expect(viewModel.invite).to.equal(false)
})
})