Commit f05607d4 by Eric Leijonmarck Committed by Sofia Papagiannaki

UserTableView: Show user name in table view (#18108)

* refactor to multiple rows

* added name for org user struct

* added name getorgusers

* added user name to tableview

* made test pass

* updated userMocks to user name field

* added missing UsersTable snapshot

* added name on teammembers page, be able to search query for name, login and email

* added the updated snapshots

* conform to same sorting as output form

* conform to previous way of using it

* sort first by login and after by email, as it was before
parent e33cf32b
...@@ -111,6 +111,7 @@ type OrgUserDTO struct { ...@@ -111,6 +111,7 @@ type OrgUserDTO struct {
OrgId int64 `json:"orgId"` OrgId int64 `json:"orgId"`
UserId int64 `json:"userId"` UserId int64 `json:"userId"`
Email string `json:"email"` Email string `json:"email"`
Name string `json:"name"`
AvatarUrl string `json:"avatarUrl"` AvatarUrl string `json:"avatarUrl"`
Login string `json:"login"` Login string `json:"login"`
Role string `json:"role"` Role string `json:"role"`
......
...@@ -70,6 +70,7 @@ type TeamMemberDTO struct { ...@@ -70,6 +70,7 @@ type TeamMemberDTO struct {
External bool `json:"-"` External bool `json:"-"`
AuthModule string `json:"auth_module"` AuthModule string `json:"auth_module"`
Email string `json:"email"` Email string `json:"email"`
Name string `json:"name"`
Login string `json:"login"` Login string `json:"login"`
AvatarUrl string `json:"avatarUrl"` AvatarUrl string `json:"avatarUrl"`
Labels []string `json:"labels"` Labels []string `json:"labels"`
......
...@@ -120,7 +120,15 @@ func GetOrgUsers(query *m.GetOrgUsersQuery) error { ...@@ -120,7 +120,15 @@ func GetOrgUsers(query *m.GetOrgUsersQuery) error {
sess.Limit(query.Limit, 0) sess.Limit(query.Limit, 0)
} }
sess.Cols("org_user.org_id", "org_user.user_id", "user.email", "user.login", "org_user.role", "user.last_seen_at") sess.Cols(
"org_user.org_id",
"org_user.user_id",
"user.email",
"user.name",
"user.login",
"org_user.role",
"user.last_seen_at",
)
sess.Asc("user.email", "user.login") sess.Asc("user.email", "user.login")
if err := sess.Find(&query.Result); err != nil { if err := sess.Find(&query.Result); err != nil {
......
...@@ -387,7 +387,17 @@ func GetTeamMembers(query *models.GetTeamMembersQuery) error { ...@@ -387,7 +387,17 @@ func GetTeamMembers(query *models.GetTeamMembersQuery) error {
if query.External { if query.External {
sess.Where("team_member.external=?", dialect.BooleanStr(true)) sess.Where("team_member.external=?", dialect.BooleanStr(true))
} }
sess.Cols("team_member.org_id", "team_member.team_id", "team_member.user_id", "user.email", "user.login", "team_member.external", "team_member.permission", "user_auth.auth_module") sess.Cols(
"team_member.org_id",
"team_member.team_id",
"team_member.user_id",
"user.email",
"user.name",
"user.login",
"team_member.external",
"team_member.permission",
"user_auth.auth_module",
)
sess.Asc("user.login", "user.email") sess.Asc("user.login", "user.email")
err := sess.Find(&query.Result) err := sess.Find(&query.Result)
......
...@@ -74,8 +74,9 @@ describe('Functions', () => { ...@@ -74,8 +74,9 @@ describe('Functions', () => {
teamId: 2, teamId: 2,
avatarUrl: '', avatarUrl: '',
email: 'user@user.org', email: 'user@user.org',
labels: [],
login: 'member', login: 'member',
name: 'member',
labels: [],
permission: TeamPermissionLevel.Member, permission: TeamPermissionLevel.Member,
}; };
const { instance } = setup({ member }); const { instance } = setup({ member });
......
...@@ -82,6 +82,7 @@ export class TeamMemberRow extends PureComponent<Props> { ...@@ -82,6 +82,7 @@ export class TeamMemberRow extends PureComponent<Props> {
</td> </td>
<td>{member.login}</td> <td>{member.login}</td>
<td>{member.email}</td> <td>{member.email}</td>
<td>{member.name}</td>
{this.renderPermissions(member)} {this.renderPermissions(member)}
{syncEnabled && this.renderLabels(member.labels)} {syncEnabled && this.renderLabels(member.labels)}
<td className="text-right"> <td className="text-right">
......
...@@ -115,8 +115,9 @@ export class TeamMembers extends PureComponent<Props, State> { ...@@ -115,8 +115,9 @@ export class TeamMembers extends PureComponent<Props, State> {
<thead> <thead>
<tr> <tr>
<th /> <th />
<th>Name</th> <th>Login</th>
<th>Email</th> <th>Email</th>
<th>Name</th>
<WithFeatureToggle featureToggle={editorsCanAdmin}> <WithFeatureToggle featureToggle={editorsCanAdmin}>
<th>Permission</th> <th>Permission</th>
</WithFeatureToggle> </WithFeatureToggle>
......
...@@ -36,6 +36,7 @@ export const getMockTeamMembers = (amount: number, teamAdminId: number): TeamMem ...@@ -36,6 +36,7 @@ export const getMockTeamMembers = (amount: number, teamAdminId: number): TeamMem
teamId: 1, teamId: 1,
avatarUrl: 'some/url/', avatarUrl: 'some/url/',
email: 'test@test.com', email: 'test@test.com',
name: 'testName',
login: `testUser-${i}`, login: `testUser-${i}`,
labels: ['label 1', 'label 2'], labels: ['label 1', 'label 2'],
permission: i === teamAdminId ? TeamPermissionLevel.Admin : TeamPermissionLevel.Member, permission: i === teamAdminId ? TeamPermissionLevel.Admin : TeamPermissionLevel.Member,
...@@ -51,6 +52,7 @@ export const getMockTeamMember = (): TeamMember => { ...@@ -51,6 +52,7 @@ export const getMockTeamMember = (): TeamMember => {
teamId: 1, teamId: 1,
avatarUrl: 'some/url/', avatarUrl: 'some/url/',
email: 'test@test.com', email: 'test@test.com',
name: 'testName',
login: 'testUser', login: 'testUser',
labels: [], labels: [],
permission: TeamPermissionLevel.Member, permission: TeamPermissionLevel.Member,
......
...@@ -18,6 +18,9 @@ exports[`Render should render team members when sync enabled 1`] = ` ...@@ -18,6 +18,9 @@ exports[`Render should render team members when sync enabled 1`] = `
<td> <td>
test@test.com test@test.com
</td> </td>
<td>
testName
</td>
<Component <Component
featureToggle={false} featureToggle={false}
> >
...@@ -71,6 +74,9 @@ exports[`Render when feature toggle editorsCanAdmin is turned off should not ren ...@@ -71,6 +74,9 @@ exports[`Render when feature toggle editorsCanAdmin is turned off should not ren
<td> <td>
test@test.com test@test.com
</td> </td>
<td>
testName
</td>
<Component <Component
featureToggle={false} featureToggle={false}
> >
...@@ -157,6 +163,9 @@ exports[`Render when feature toggle editorsCanAdmin is turned on should render p ...@@ -157,6 +163,9 @@ exports[`Render when feature toggle editorsCanAdmin is turned on should render p
<td> <td>
test@test.com test@test.com
</td> </td>
<td>
testName
</td>
<Component <Component
featureToggle={true} featureToggle={true}
> >
...@@ -243,6 +252,9 @@ exports[`Render when feature toggle editorsCanAdmin is turned on should render s ...@@ -243,6 +252,9 @@ exports[`Render when feature toggle editorsCanAdmin is turned on should render s
<td> <td>
test@test.com test@test.com
</td> </td>
<td>
testName
</td>
<Component <Component
featureToggle={true} featureToggle={true}
> >
......
...@@ -64,11 +64,14 @@ exports[`Render should render component 1`] = ` ...@@ -64,11 +64,14 @@ exports[`Render should render component 1`] = `
<tr> <tr>
<th /> <th />
<th> <th>
Name Login
</th> </th>
<th> <th>
Email Email
</th> </th>
<th>
Name
</th>
<Component <Component
featureToggle={false} featureToggle={false}
> >
...@@ -155,11 +158,14 @@ exports[`Render should render team members 1`] = ` ...@@ -155,11 +158,14 @@ exports[`Render should render team members 1`] = `
<tr> <tr>
<th /> <th />
<th> <th>
Name Login
</th> </th>
<th> <th>
Email Email
</th> </th>
<th>
Name
</th>
<Component <Component
featureToggle={false} featureToggle={false}
> >
...@@ -189,6 +195,7 @@ exports[`Render should render team members 1`] = ` ...@@ -189,6 +195,7 @@ exports[`Render should render team members 1`] = `
"label 2", "label 2",
], ],
"login": "testUser-1", "login": "testUser-1",
"name": "testName",
"permission": 0, "permission": 0,
"teamId": 1, "teamId": 1,
"userId": 1, "userId": 1,
...@@ -209,6 +216,7 @@ exports[`Render should render team members 1`] = ` ...@@ -209,6 +216,7 @@ exports[`Render should render team members 1`] = `
"label 2", "label 2",
], ],
"login": "testUser-2", "login": "testUser-2",
"name": "testName",
"permission": 0, "permission": 0,
"teamId": 1, "teamId": 1,
"userId": 2, "userId": 2,
...@@ -229,6 +237,7 @@ exports[`Render should render team members 1`] = ` ...@@ -229,6 +237,7 @@ exports[`Render should render team members 1`] = `
"label 2", "label 2",
], ],
"login": "testUser-3", "login": "testUser-3",
"name": "testName",
"permission": 0, "permission": 0,
"teamId": 1, "teamId": 1,
"userId": 3, "userId": 3,
...@@ -249,6 +258,7 @@ exports[`Render should render team members 1`] = ` ...@@ -249,6 +258,7 @@ exports[`Render should render team members 1`] = `
"label 2", "label 2",
], ],
"login": "testUser-4", "login": "testUser-4",
"name": "testName",
"permission": 0, "permission": 0,
"teamId": 1, "teamId": 1,
"userId": 4, "userId": 4,
...@@ -269,6 +279,7 @@ exports[`Render should render team members 1`] = ` ...@@ -269,6 +279,7 @@ exports[`Render should render team members 1`] = `
"label 2", "label 2",
], ],
"login": "testUser-5", "login": "testUser-5",
"name": "testName",
"permission": 4, "permission": 4,
"teamId": 1, "teamId": 1,
"userId": 5, "userId": 5,
......
...@@ -26,7 +26,7 @@ export const getTeamMembers = (state: TeamState) => { ...@@ -26,7 +26,7 @@ export const getTeamMembers = (state: TeamState) => {
const regex = RegExp(state.searchMemberQuery, 'i'); const regex = RegExp(state.searchMemberQuery, 'i');
return state.members.filter(member => { return state.members.filter(member => {
return regex.test(member.login) || regex.test(member.email); return regex.test(member.login) || regex.test(member.email) || regex.test(member.name);
}); });
}; };
......
...@@ -49,7 +49,7 @@ export class UsersActionBar extends PureComponent<Props> { ...@@ -49,7 +49,7 @@ export class UsersActionBar extends PureComponent<Props> {
inputClassName="gf-form-input width-20" inputClassName="gf-form-input width-20"
value={searchQuery} value={searchQuery}
onChange={setUsersSearchQuery} onChange={setUsersSearchQuery}
placeholder="Filter by name or type" placeholder="Filter by email, login or name"
/> />
{pendingInvitesCount > 0 && ( {pendingInvitesCount > 0 && (
<div style={{ marginLeft: '1rem' }}> <div style={{ marginLeft: '1rem' }}>
......
...@@ -17,6 +17,7 @@ const UsersTable: FC<Props> = props => { ...@@ -17,6 +17,7 @@ const UsersTable: FC<Props> = props => {
<th /> <th />
<th>Login</th> <th>Login</th>
<th>Email</th> <th>Email</th>
<th>Name</th>
<th>Seen</th> <th>Seen</th>
<th>Role</th> <th>Role</th>
<th style={{ width: '34px' }} /> <th style={{ width: '34px' }} />
...@@ -33,6 +34,7 @@ const UsersTable: FC<Props> = props => { ...@@ -33,6 +34,7 @@ const UsersTable: FC<Props> = props => {
<td> <td>
<span className="ellipsis">{user.email}</span> <span className="ellipsis">{user.email}</span>
</td> </td>
<td>{user.name}</td>
<td>{user.lastSeenAtAge}</td> <td>{user.lastSeenAtAge}</td>
<td> <td>
<div className="gf-form-select-wrapper width-12"> <div className="gf-form-select-wrapper width-12">
......
...@@ -5,6 +5,7 @@ export const getMockUsers = (amount: number) => { ...@@ -5,6 +5,7 @@ export const getMockUsers = (amount: number) => {
users.push({ users.push({
avatarUrl: 'url/to/avatar', avatarUrl: 'url/to/avatar',
email: `user-${i}@test.com`, email: `user-${i}@test.com`,
name: `user-${i} test`,
lastSeenAt: '2018-10-01', lastSeenAt: '2018-10-01',
lastSeenAtAge: '', lastSeenAtAge: '',
login: `user-${i}`, login: `user-${i}`,
...@@ -21,6 +22,7 @@ export const getMockUser = () => { ...@@ -21,6 +22,7 @@ export const getMockUser = () => {
return { return {
avatarUrl: 'url/to/avatar', avatarUrl: 'url/to/avatar',
email: `user@test.com`, email: `user@test.com`,
name: 'user test',
lastSeenAt: '2018-10-01', lastSeenAt: '2018-10-01',
lastSeenAtAge: '', lastSeenAtAge: '',
login: `user`, login: `user`,
......
...@@ -11,7 +11,7 @@ exports[`Render should render component 1`] = ` ...@@ -11,7 +11,7 @@ exports[`Render should render component 1`] = `
inputClassName="gf-form-input width-20" inputClassName="gf-form-input width-20"
labelClassName="gf-form--has-input-icon" labelClassName="gf-form--has-input-icon"
onChange={[MockFunction]} onChange={[MockFunction]}
placeholder="Filter by name or type" placeholder="Filter by email, login or name"
value="" value=""
/> />
<div <div
...@@ -32,7 +32,7 @@ exports[`Render should render pending invites button 1`] = ` ...@@ -32,7 +32,7 @@ exports[`Render should render pending invites button 1`] = `
inputClassName="gf-form-input width-20" inputClassName="gf-form-input width-20"
labelClassName="gf-form--has-input-icon" labelClassName="gf-form--has-input-icon"
onChange={[MockFunction]} onChange={[MockFunction]}
placeholder="Filter by name or type" placeholder="Filter by email, login or name"
value="" value=""
/> />
<div <div
...@@ -77,7 +77,7 @@ exports[`Render should show external user management button 1`] = ` ...@@ -77,7 +77,7 @@ exports[`Render should show external user management button 1`] = `
inputClassName="gf-form-input width-20" inputClassName="gf-form-input width-20"
labelClassName="gf-form--has-input-icon" labelClassName="gf-form--has-input-icon"
onChange={[MockFunction]} onChange={[MockFunction]}
placeholder="Filter by name or type" placeholder="Filter by email, login or name"
value="" value=""
/> />
<div <div
...@@ -104,7 +104,7 @@ exports[`Render should show invite button 1`] = ` ...@@ -104,7 +104,7 @@ exports[`Render should show invite button 1`] = `
inputClassName="gf-form-input width-20" inputClassName="gf-form-input width-20"
labelClassName="gf-form--has-input-icon" labelClassName="gf-form--has-input-icon"
onChange={[MockFunction]} onChange={[MockFunction]}
placeholder="Filter by name or type" placeholder="Filter by email, login or name"
value="" value=""
/> />
<div <div
......
...@@ -14,6 +14,9 @@ exports[`Render should render component 1`] = ` ...@@ -14,6 +14,9 @@ exports[`Render should render component 1`] = `
Email Email
</th> </th>
<th> <th>
Name
</th>
<th>
Seen Seen
</th> </th>
<th> <th>
...@@ -46,6 +49,9 @@ exports[`Render should render users table 1`] = ` ...@@ -46,6 +49,9 @@ exports[`Render should render users table 1`] = `
Email Email
</th> </th>
<th> <th>
Name
</th>
<th>
Seen Seen
</th> </th>
<th> <th>
...@@ -82,6 +88,9 @@ exports[`Render should render users table 1`] = ` ...@@ -82,6 +88,9 @@ exports[`Render should render users table 1`] = `
user-0@test.com user-0@test.com
</span> </span>
</td> </td>
<td>
user-0 test
</td>
<td /> <td />
<td> <td>
<div <div
...@@ -145,6 +154,9 @@ exports[`Render should render users table 1`] = ` ...@@ -145,6 +154,9 @@ exports[`Render should render users table 1`] = `
user-1@test.com user-1@test.com
</span> </span>
</td> </td>
<td>
user-1 test
</td>
<td /> <td />
<td> <td>
<div <div
...@@ -208,6 +220,9 @@ exports[`Render should render users table 1`] = ` ...@@ -208,6 +220,9 @@ exports[`Render should render users table 1`] = `
user-2@test.com user-2@test.com
</span> </span>
</td> </td>
<td>
user-2 test
</td>
<td /> <td />
<td> <td>
<div <div
...@@ -271,6 +286,9 @@ exports[`Render should render users table 1`] = ` ...@@ -271,6 +286,9 @@ exports[`Render should render users table 1`] = `
user-3@test.com user-3@test.com
</span> </span>
</td> </td>
<td>
user-3 test
</td>
<td /> <td />
<td> <td>
<div <div
...@@ -334,6 +352,9 @@ exports[`Render should render users table 1`] = ` ...@@ -334,6 +352,9 @@ exports[`Render should render users table 1`] = `
user-4@test.com user-4@test.com
</span> </span>
</td> </td>
<td>
user-4 test
</td>
<td /> <td />
<td> <td>
<div <div
...@@ -397,6 +418,9 @@ exports[`Render should render users table 1`] = ` ...@@ -397,6 +418,9 @@ exports[`Render should render users table 1`] = `
user-5@test.com user-5@test.com
</span> </span>
</td> </td>
<td>
user-5 test
</td>
<td /> <td />
<td> <td>
<div <div
......
...@@ -4,7 +4,7 @@ export const getUsers = (state: UsersState) => { ...@@ -4,7 +4,7 @@ export const getUsers = (state: UsersState) => {
const regex = new RegExp(state.searchQuery, 'i'); const regex = new RegExp(state.searchQuery, 'i');
return state.users.filter(user => { return state.users.filter(user => {
return regex.test(user.login) || regex.test(user.email); return regex.test(user.login) || regex.test(user.email) || regex.test(user.name);
}); });
}; };
......
...@@ -14,6 +14,7 @@ export interface TeamMember { ...@@ -14,6 +14,7 @@ export interface TeamMember {
teamId: number; teamId: number;
avatarUrl: string; avatarUrl: string;
email: string; email: string;
name: string;
login: string; login: string;
labels: string[]; labels: string[];
permission: number; permission: number;
......
...@@ -6,6 +6,7 @@ export interface OrgUser { ...@@ -6,6 +6,7 @@ export interface OrgUser {
lastSeenAt: string; lastSeenAt: string;
lastSeenAtAge: string; lastSeenAtAge: string;
login: string; login: string;
name: string;
orgId: number; orgId: number;
role: string; role: string;
userId: number; userId: number;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment