Commit da68b858 by Marcus Efraimsson

display team member labels

parent 9a6446c2
......@@ -12,6 +12,7 @@ const setup = (propOverrides?: object) => {
loadTeamMembers: jest.fn(),
addTeamMember: jest.fn(),
removeTeamMember: jest.fn(),
syncEnabled: false,
};
Object.assign(props, propOverrides);
......@@ -39,6 +40,15 @@ describe('Render', () => {
expect(wrapper).toMatchSnapshot();
});
it('should render team members when sync enabled', () => {
const { wrapper } = setup({
members: getMockTeamMembers(5),
syncEnabled: true,
});
expect(wrapper).toMatchSnapshot();
});
});
describe('Functions', () => {
......
......@@ -3,6 +3,7 @@ import { connect } from 'react-redux';
import SlideDown from 'app/core/components/Animations/SlideDown';
import { UserPicker, User } from 'app/core/components/Picker/UserPicker';
import DeleteButton from 'app/core/components/DeleteButton/DeleteButton';
import { TagBadge } from 'app/core/components/TagFilter/TagBadge';
import { TeamMember } from '../../types';
import { loadTeamMembers, addTeamMember, removeTeamMember, setSearchMemberQuery } from './state/actions';
import { getSearchMemberQuery, getTeamMembers } from './state/selectors';
......@@ -14,6 +15,7 @@ export interface Props {
addTeamMember: typeof addTeamMember;
removeTeamMember: typeof removeTeamMember;
setSearchMemberQuery: typeof setSearchMemberQuery;
syncEnabled: boolean;
}
export interface State {
......@@ -52,7 +54,19 @@ export class TeamMembers extends PureComponent<Props, State> {
this.setState({ newTeamMember: null });
};
renderMember(member: TeamMember) {
renderLabels(labels: string[]) {
if (!labels) {
return <td />;
}
return (
<td>
{labels.map(label => <TagBadge key={label} label={label} removeIcon={false} count={0} onClick={() => {}} />)}
</td>
);
}
renderMember(member: TeamMember, syncEnabled: boolean) {
return (
<tr key={member.userId}>
<td className="width-4 text-center">
......@@ -60,6 +74,7 @@ export class TeamMembers extends PureComponent<Props, State> {
</td>
<td>{member.login}</td>
<td>{member.email}</td>
{syncEnabled ? this.renderLabels(member.labels) : ''}
<td className="text-right">
<DeleteButton onConfirmDelete={() => this.onRemoveMember(member)} />
</td>
......@@ -69,7 +84,7 @@ export class TeamMembers extends PureComponent<Props, State> {
render() {
const { newTeamMember, isAdding } = this.state;
const { searchMemberQuery, members } = this.props;
const { searchMemberQuery, members, syncEnabled } = this.props;
const newTeamMemberValue = newTeamMember && newTeamMember.id.toString();
return (
......@@ -120,10 +135,11 @@ export class TeamMembers extends PureComponent<Props, State> {
<th />
<th>Name</th>
<th>Email</th>
{syncEnabled ? <th /> : ''}
<th style={{ width: '1%' }} />
</tr>
</thead>
<tbody>{members && members.map(member => this.renderMember(member))}</tbody>
<tbody>{members && members.map(member => this.renderMember(member, syncEnabled))}</tbody>
</table>
</div>
</div>
......
......@@ -63,7 +63,7 @@ export class TeamPages extends PureComponent<Props, State> {
switch (currentPage) {
case PageTypes.Members:
return <TeamMembers />;
return <TeamMembers syncEnabled={isSyncEnabled} />;
case PageTypes.Settings:
return <TeamSettings />;
......
......@@ -35,6 +35,7 @@ export const getMockTeamMembers = (amount: number): TeamMember[] => {
avatarUrl: 'some/url/',
email: 'test@test.com',
login: `testUser-${i}`,
labels: ['label 1', 'label 2'],
});
}
......@@ -48,6 +49,7 @@ export const getMockTeamMember = (): TeamMember => {
avatarUrl: 'some/url/',
email: 'test@test.com',
login: 'testUser',
labels: [],
};
};
......
......@@ -315,3 +315,305 @@ exports[`Render should render team members 1`] = `
</div>
</div>
`;
exports[`Render should render team members when sync enabled 1`] = `
<div>
<div
className="page-action-bar"
>
<div
className="gf-form gf-form--grow"
>
<label
className="gf-form--has-input-icon gf-form--grow"
>
<input
className="gf-form-input"
onChange={[Function]}
placeholder="Search members"
type="text"
value=""
/>
<i
className="gf-form-input-icon fa fa-search"
/>
</label>
</div>
<div
className="page-action-bar__spacer"
/>
<button
className="btn btn-success pull-right"
disabled={false}
onClick={[Function]}
>
<i
className="fa fa-plus"
/>
Add a member
</button>
</div>
<Component
in={false}
>
<div
className="cta-form"
>
<button
className="cta-form__close btn btn-transparent"
onClick={[Function]}
>
<i
className="fa fa-close"
/>
</button>
<h5>
Add Team Member
</h5>
<div
className="gf-form-inline"
>
<UserPicker
className="width-30"
onSelected={[Function]}
value={null}
/>
</div>
</div>
</Component>
<div
className="admin-list-table"
>
<table
className="filter-table filter-table--hover form-inline"
>
<thead>
<tr>
<th />
<th>
Name
</th>
<th>
Email
</th>
<th />
<th
style={
Object {
"width": "1%",
}
}
/>
</tr>
</thead>
<tbody>
<tr
key="1"
>
<td
className="width-4 text-center"
>
<img
className="filter-table__avatar"
src="some/url/"
/>
</td>
<td>
testUser-1
</td>
<td>
test@test.com
</td>
<td>
<TagBadge
count={0}
key="label 1"
label="label 1"
onClick={[Function]}
removeIcon={false}
/>
<TagBadge
count={0}
key="label 2"
label="label 2"
onClick={[Function]}
removeIcon={false}
/>
</td>
<td
className="text-right"
>
<DeleteButton
onConfirmDelete={[Function]}
/>
</td>
</tr>
<tr
key="2"
>
<td
className="width-4 text-center"
>
<img
className="filter-table__avatar"
src="some/url/"
/>
</td>
<td>
testUser-2
</td>
<td>
test@test.com
</td>
<td>
<TagBadge
count={0}
key="label 1"
label="label 1"
onClick={[Function]}
removeIcon={false}
/>
<TagBadge
count={0}
key="label 2"
label="label 2"
onClick={[Function]}
removeIcon={false}
/>
</td>
<td
className="text-right"
>
<DeleteButton
onConfirmDelete={[Function]}
/>
</td>
</tr>
<tr
key="3"
>
<td
className="width-4 text-center"
>
<img
className="filter-table__avatar"
src="some/url/"
/>
</td>
<td>
testUser-3
</td>
<td>
test@test.com
</td>
<td>
<TagBadge
count={0}
key="label 1"
label="label 1"
onClick={[Function]}
removeIcon={false}
/>
<TagBadge
count={0}
key="label 2"
label="label 2"
onClick={[Function]}
removeIcon={false}
/>
</td>
<td
className="text-right"
>
<DeleteButton
onConfirmDelete={[Function]}
/>
</td>
</tr>
<tr
key="4"
>
<td
className="width-4 text-center"
>
<img
className="filter-table__avatar"
src="some/url/"
/>
</td>
<td>
testUser-4
</td>
<td>
test@test.com
</td>
<td>
<TagBadge
count={0}
key="label 1"
label="label 1"
onClick={[Function]}
removeIcon={false}
/>
<TagBadge
count={0}
key="label 2"
label="label 2"
onClick={[Function]}
removeIcon={false}
/>
</td>
<td
className="text-right"
>
<DeleteButton
onConfirmDelete={[Function]}
/>
</td>
</tr>
<tr
key="5"
>
<td
className="width-4 text-center"
>
<img
className="filter-table__avatar"
src="some/url/"
/>
</td>
<td>
testUser-5
</td>
<td>
test@test.com
</td>
<td>
<TagBadge
count={0}
key="label 1"
label="label 1"
onClick={[Function]}
removeIcon={false}
/>
<TagBadge
count={0}
key="label 2"
label="label 2"
onClick={[Function]}
removeIcon={false}
/>
</td>
<td
className="text-right"
>
<DeleteButton
onConfirmDelete={[Function]}
/>
</td>
</tr>
</tbody>
</table>
</div>
</div>
`;
......@@ -29,7 +29,9 @@ exports[`Render should render member page if team not empty 1`] = `
<div
className="page-container page-body"
>
<Connect(TeamMembers) />
<Connect(TeamMembers)
syncEnabled={true}
/>
</div>
</div>
`;
......
......@@ -12,6 +12,7 @@ export interface TeamMember {
avatarUrl: string;
email: string;
login: string;
labels: string[];
}
export interface TeamGroup {
......
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