diff --git a/app/scenes/Settings/People.js b/app/scenes/Settings/People.js index 0f00999f..838d5507 100644 --- a/app/scenes/Settings/People.js +++ b/app/scenes/Settings/People.js @@ -32,9 +32,8 @@ class People extends React.Component {

People

- Everyone that has signed in to your Outline appears here. It's - possible that there are other people who have access but haven't - signed in yet. + Everyone that has signed in to your Outline appear here. It’s possible + that there are other people who have access but haven’t signed in yet. @@ -42,7 +41,7 @@ class People extends React.Component { ))} diff --git a/app/scenes/Settings/components/UserListItem.js b/app/scenes/Settings/components/UserListItem.js index e62eb321..924f4d75 100644 --- a/app/scenes/Settings/components/UserListItem.js +++ b/app/scenes/Settings/components/UserListItem.js @@ -1,5 +1,6 @@ // @flow import * as React from 'react'; +import distanceInWordsToNow from 'date-fns/distance_in_words_to_now'; import styled from 'styled-components'; import UserMenu from 'menus/UserMenu'; @@ -9,10 +10,10 @@ import type { User } from '../../../types'; type Props = { user: User, - isCurrentUser: boolean, + showMenu: boolean, }; -const UserListItem = ({ user, isCurrentUser }: Props) => { +const UserListItem = ({ user, showMenu }: Props) => { return ( { image={} subtitle={ - {user.username ? user.username : user.email} + {user.email ? `${user.email} · ` : undefined} + {`Joined ${distanceInWordsToNow(user.createdAt)} ago`} {user.isAdmin && Admin} {user.isSuspended && Suspended} } - actions={isCurrentUser ? undefined : } + actions={showMenu ? : undefined} /> ); }; diff --git a/app/types/index.js b/app/types/index.js index 8b629d96..46cb2793 100644 --- a/app/types/index.js +++ b/app/types/index.js @@ -7,6 +7,7 @@ export type User = { username: string, isAdmin?: boolean, isSuspended?: boolean, + createdAt: string, }; export type Toast = { diff --git a/server/api/__snapshots__/team.test.js.snap b/server/api/__snapshots__/team.test.js.snap index eac4cccf..a92a594e 100644 --- a/server/api/__snapshots__/team.test.js.snap +++ b/server/api/__snapshots__/team.test.js.snap @@ -5,12 +5,14 @@ Object { "data": Array [ Object { "avatarUrl": "http://example.com/avatar.png", + "createdAt": "2018-01-01T00:00:00.000Z", "id": "fa952cff-fa64-4d42-a6ea-6955c9689046", "name": "Admin User", "username": "admin", }, Object { "avatarUrl": "http://example.com/avatar.png", + "createdAt": "2018-01-01T00:00:00.000Z", "id": "46fde1d4-0050-428f-9f0b-0bf77f4bdf61", "name": "User 1", "username": "user1", @@ -31,15 +33,7 @@ Object { "data": Array [ Object { "avatarUrl": "http://example.com/avatar.png", - "email": "admin@example.com", - "id": "fa952cff-fa64-4d42-a6ea-6955c9689046", - "isAdmin": true, - "isSuspended": false, - "name": "Admin User", - "username": "admin", - }, - Object { - "avatarUrl": "http://example.com/avatar.png", + "createdAt": "2018-01-01T00:00:00.000Z", "email": "user1@example.com", "id": "46fde1d4-0050-428f-9f0b-0bf77f4bdf61", "isAdmin": false, @@ -47,6 +41,16 @@ Object { "name": "User 1", "username": "user1", }, + Object { + "avatarUrl": "http://example.com/avatar.png", + "createdAt": "2018-01-01T00:00:00.000Z", + "email": "admin@example.com", + "id": "fa952cff-fa64-4d42-a6ea-6955c9689046", + "isAdmin": true, + "isSuspended": false, + "name": "Admin User", + "username": "admin", + }, ], "ok": true, "pagination": Object { diff --git a/server/api/__snapshots__/user.test.js.snap b/server/api/__snapshots__/user.test.js.snap index 40a7610d..451c115c 100644 --- a/server/api/__snapshots__/user.test.js.snap +++ b/server/api/__snapshots__/user.test.js.snap @@ -4,6 +4,7 @@ exports[`#user.activate should activate a suspended user 1`] = ` Object { "data": Object { "avatarUrl": "http://example.com/avatar.png", + "createdAt": "2018-01-01T00:00:00.000Z", "email": "user1@example.com", "id": "46fde1d4-0050-428f-9f0b-0bf77f4bdf61", "isAdmin": false, @@ -29,6 +30,7 @@ exports[`#user.demote should demote an admin 1`] = ` Object { "data": Object { "avatarUrl": "http://example.com/avatar.png", + "createdAt": "2018-01-01T00:00:00.000Z", "email": "user1@example.com", "id": "46fde1d4-0050-428f-9f0b-0bf77f4bdf61", "isAdmin": false, @@ -72,6 +74,7 @@ exports[`#user.info should return known user 1`] = ` Object { "data": Object { "avatarUrl": "http://example.com/avatar.png", + "createdAt": "2018-01-01T00:00:00.000Z", "id": "46fde1d4-0050-428f-9f0b-0bf77f4bdf61", "name": "User 1", "username": "user1", @@ -85,6 +88,7 @@ exports[`#user.promote should promote a new admin 1`] = ` Object { "data": Object { "avatarUrl": "http://example.com/avatar.png", + "createdAt": "2018-01-01T00:00:00.000Z", "email": "user1@example.com", "id": "46fde1d4-0050-428f-9f0b-0bf77f4bdf61", "isAdmin": true, @@ -119,6 +123,7 @@ exports[`#user.suspend should suspend an user 1`] = ` Object { "data": Object { "avatarUrl": "http://example.com/avatar.png", + "createdAt": "2018-01-01T00:00:00.000Z", "email": "user1@example.com", "id": "46fde1d4-0050-428f-9f0b-0bf77f4bdf61", "isAdmin": false, @@ -153,6 +158,7 @@ exports[`#user.update should update user profile information 1`] = ` Object { "data": Object { "avatarUrl": "http://example.com/avatar.png", + "createdAt": "2018-01-01T00:00:00.000Z", "email": "user1@example.com", "id": "46fde1d4-0050-428f-9f0b-0bf77f4bdf61", "isAdmin": false, diff --git a/server/presenters/__snapshots__/user.test.js.snap b/server/presenters/__snapshots__/user.test.js.snap index a4e6bd70..b30d948f 100644 --- a/server/presenters/__snapshots__/user.test.js.snap +++ b/server/presenters/__snapshots__/user.test.js.snap @@ -3,6 +3,7 @@ exports[`presents a user 1`] = ` Object { "avatarUrl": "http://example.com/avatar.png", + "createdAt": undefined, "id": "123", "name": "Test User", "username": "testuser", @@ -12,6 +13,7 @@ Object { exports[`presents a user without slack data 1`] = ` Object { "avatarUrl": null, + "createdAt": undefined, "id": "123", "name": "Test User", "username": "testuser", diff --git a/server/presenters/user.js b/server/presenters/user.js index 767e3e7e..82283ff3 100644 --- a/server/presenters/user.js +++ b/server/presenters/user.js @@ -21,6 +21,7 @@ export default ( ): UserPresentation => { const userData = {}; userData.id = user.id; + userData.createdAt = user.createdAt; userData.username = user.username; userData.name = user.name; userData.avatarUrl = diff --git a/server/test/factories.js b/server/test/factories.js index 0d8b4ebe..7cdcee64 100644 --- a/server/test/factories.js +++ b/server/test/factories.js @@ -42,6 +42,7 @@ export async function buildUser(overrides: Object = {}) { password: 'test123!', service: 'slack', serviceId: uuid.v4(), + createdAt: new Date('2018-01-01T00:00:00.000Z'), ...overrides, }); } diff --git a/server/test/support.js b/server/test/support.js index 826c8ffa..2f57376d 100644 --- a/server/test/support.js +++ b/server/test/support.js @@ -36,6 +36,7 @@ const seed = async () => { id: 'U2399UF2P', image_192: 'http://example.com/avatar.png', }, + createdAt: new Date('2018-01-01T00:00:00.000Z'), }); const admin = await User.create({ @@ -52,6 +53,7 @@ const seed = async () => { id: 'U2399UF1P', image_192: 'http://example.com/avatar.png', }, + createdAt: new Date('2018-01-01T00:00:00.000Z'), }); const collection = await Collection.create({