Commit 7888457a by Hugo Häggmark Committed by Leonard Gram

teams: basic ui for permission in team members view

parent af4994ba
......@@ -55,12 +55,13 @@ type GetTeamMembersQuery struct {
// Projections and DTOs
type TeamMemberDTO struct {
OrgId int64 `json:"orgId"`
TeamId int64 `json:"teamId"`
UserId int64 `json:"userId"`
External bool `json:"-"`
Email string `json:"email"`
Login string `json:"login"`
AvatarUrl string `json:"avatarUrl"`
Labels []string `json:"labels"`
OrgId int64 `json:"orgId"`
TeamId int64 `json:"teamId"`
UserId int64 `json:"userId"`
External bool `json:"-"`
Email string `json:"email"`
Login string `json:"login"`
AvatarUrl string `json:"avatarUrl"`
Labels []string `json:"labels"`
Permission int64 `json:"permission"`
}
......@@ -294,7 +294,7 @@ func GetTeamMembers(query *m.GetTeamMembersQuery) error {
if query.External {
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")
sess.Cols("team_member.org_id", "team_member.team_id", "team_member.user_id", "user.email", "user.login", "team_member.external", "team_member.permission")
sess.Asc("user.login", "user.email")
err := sess.Find(&query.Result)
......
......@@ -2,9 +2,9 @@ import React, { PureComponent } from 'react';
import { connect } from 'react-redux';
import SlideDown from 'app/core/components/Animations/SlideDown';
import { UserPicker } from 'app/core/components/Select/UserPicker';
import { DeleteButton } from '@grafana/ui';
import { DeleteButton, Select } from '@grafana/ui';
import { TagBadge } from 'app/core/components/TagFilter/TagBadge';
import { TeamMember, User } from 'app/types';
import { TeamMember, User, teamsPermissionLevels } from 'app/types';
import { loadTeamMembers, addTeamMember, removeTeamMember, setSearchMemberQuery } from './state/actions';
import { getSearchMemberQuery, getTeamMembers } from './state/selectors';
import { FilterInput } from 'app/core/components/FilterInput/FilterInput';
......@@ -70,6 +70,7 @@ export class TeamMembers extends PureComponent<Props, State> {
}
renderMember(member: TeamMember, syncEnabled: boolean) {
const currentPermissionLevel = teamsPermissionLevels.find(dp => dp.value === member.permission);
return (
<tr key={member.userId}>
<td className="width-4 text-center">
......@@ -77,6 +78,18 @@ export class TeamMembers extends PureComponent<Props, State> {
</td>
<td>{member.login}</td>
<td>{member.email}</td>
<td>
<div className="gf-form">
<Select
isSearchable={false}
options={teamsPermissionLevels}
onChange={() => {}}
className="gf-form-select-box__control--menu-right"
value={currentPermissionLevel}
isDisabled={true}
/>
</div>
</td>{' '}
{syncEnabled && this.renderLabels(member.labels)}
<td className="text-right">
<DeleteButton onConfirm={() => this.onRemoveMember(member)} />
......@@ -132,6 +145,7 @@ export class TeamMembers extends PureComponent<Props, State> {
<th />
<th>Name</th>
<th>Email</th>
<th>Permission</th>
{syncEnabled && <th />}
<th style={{ width: '1%' }} />
</tr>
......
......@@ -36,6 +36,7 @@ export const getMockTeamMembers = (amount: number): TeamMember[] => {
email: 'test@test.com',
login: `testUser-${i}`,
labels: ['label 1', 'label 2'],
permission: 0,
});
}
......@@ -50,6 +51,7 @@ export const getMockTeamMember = (): TeamMember => {
email: 'test@test.com',
login: 'testUser',
labels: [],
permission: 0,
};
};
......
......@@ -69,6 +69,9 @@ exports[`Render should render component 1`] = `
<th>
Email
</th>
<th>
Permission
</th>
<th
style={
Object {
......@@ -153,6 +156,9 @@ exports[`Render should render team members 1`] = `
<th>
Email
</th>
<th>
Permission
</th>
<th
style={
Object {
......@@ -180,6 +186,48 @@ exports[`Render should render team members 1`] = `
<td>
test@test.com
</td>
<td>
<div
className="gf-form"
>
<Select
autoFocus={false}
backspaceRemovesValue={true}
className="gf-form-select-box__control--menu-right"
isClearable={false}
isDisabled={true}
isLoading={false}
isMulti={false}
isSearchable={false}
maxMenuHeight={300}
onChange={[Function]}
openMenuOnFocus={false}
options={
Array [
Object {
"description": "Is team member",
"label": "Member",
"value": 0,
},
Object {
"description": "Can add/remove permissions and delete team.",
"label": "Admin",
"value": 4,
},
]
}
value={
Object {
"description": "Is team member",
"label": "Member",
"value": 0,
}
}
width={null}
/>
</div>
</td>
<td
className="text-right"
>
......@@ -205,6 +253,48 @@ exports[`Render should render team members 1`] = `
<td>
test@test.com
</td>
<td>
<div
className="gf-form"
>
<Select
autoFocus={false}
backspaceRemovesValue={true}
className="gf-form-select-box__control--menu-right"
isClearable={false}
isDisabled={true}
isLoading={false}
isMulti={false}
isSearchable={false}
maxMenuHeight={300}
onChange={[Function]}
openMenuOnFocus={false}
options={
Array [
Object {
"description": "Is team member",
"label": "Member",
"value": 0,
},
Object {
"description": "Can add/remove permissions and delete team.",
"label": "Admin",
"value": 4,
},
]
}
value={
Object {
"description": "Is team member",
"label": "Member",
"value": 0,
}
}
width={null}
/>
</div>
</td>
<td
className="text-right"
>
......@@ -230,6 +320,48 @@ exports[`Render should render team members 1`] = `
<td>
test@test.com
</td>
<td>
<div
className="gf-form"
>
<Select
autoFocus={false}
backspaceRemovesValue={true}
className="gf-form-select-box__control--menu-right"
isClearable={false}
isDisabled={true}
isLoading={false}
isMulti={false}
isSearchable={false}
maxMenuHeight={300}
onChange={[Function]}
openMenuOnFocus={false}
options={
Array [
Object {
"description": "Is team member",
"label": "Member",
"value": 0,
},
Object {
"description": "Can add/remove permissions and delete team.",
"label": "Admin",
"value": 4,
},
]
}
value={
Object {
"description": "Is team member",
"label": "Member",
"value": 0,
}
}
width={null}
/>
</div>
</td>
<td
className="text-right"
>
......@@ -255,6 +387,48 @@ exports[`Render should render team members 1`] = `
<td>
test@test.com
</td>
<td>
<div
className="gf-form"
>
<Select
autoFocus={false}
backspaceRemovesValue={true}
className="gf-form-select-box__control--menu-right"
isClearable={false}
isDisabled={true}
isLoading={false}
isMulti={false}
isSearchable={false}
maxMenuHeight={300}
onChange={[Function]}
openMenuOnFocus={false}
options={
Array [
Object {
"description": "Is team member",
"label": "Member",
"value": 0,
},
Object {
"description": "Can add/remove permissions and delete team.",
"label": "Admin",
"value": 4,
},
]
}
value={
Object {
"description": "Is team member",
"label": "Member",
"value": 0,
}
}
width={null}
/>
</div>
</td>
<td
className="text-right"
>
......@@ -280,6 +454,48 @@ exports[`Render should render team members 1`] = `
<td>
test@test.com
</td>
<td>
<div
className="gf-form"
>
<Select
autoFocus={false}
backspaceRemovesValue={true}
className="gf-form-select-box__control--menu-right"
isClearable={false}
isDisabled={true}
isLoading={false}
isMulti={false}
isSearchable={false}
maxMenuHeight={300}
onChange={[Function]}
openMenuOnFocus={false}
options={
Array [
Object {
"description": "Is team member",
"label": "Member",
"value": 0,
},
Object {
"description": "Can add/remove permissions and delete team.",
"label": "Admin",
"value": 4,
},
]
}
value={
Object {
"description": "Is team member",
"label": "Member",
"value": 0,
}
}
width={null}
/>
</div>
</td>
<td
className="text-right"
>
......@@ -363,6 +579,9 @@ exports[`Render should render team members when sync enabled 1`] = `
<th>
Email
</th>
<th>
Permission
</th>
<th />
<th
style={
......@@ -392,6 +611,48 @@ exports[`Render should render team members when sync enabled 1`] = `
test@test.com
</td>
<td>
<div
className="gf-form"
>
<Select
autoFocus={false}
backspaceRemovesValue={true}
className="gf-form-select-box__control--menu-right"
isClearable={false}
isDisabled={true}
isLoading={false}
isMulti={false}
isSearchable={false}
maxMenuHeight={300}
onChange={[Function]}
openMenuOnFocus={false}
options={
Array [
Object {
"description": "Is team member",
"label": "Member",
"value": 0,
},
Object {
"description": "Can add/remove permissions and delete team.",
"label": "Admin",
"value": 4,
},
]
}
value={
Object {
"description": "Is team member",
"label": "Member",
"value": 0,
}
}
width={null}
/>
</div>
</td>
<td>
<TagBadge
count={0}
key="label 1"
......@@ -433,6 +694,48 @@ exports[`Render should render team members when sync enabled 1`] = `
test@test.com
</td>
<td>
<div
className="gf-form"
>
<Select
autoFocus={false}
backspaceRemovesValue={true}
className="gf-form-select-box__control--menu-right"
isClearable={false}
isDisabled={true}
isLoading={false}
isMulti={false}
isSearchable={false}
maxMenuHeight={300}
onChange={[Function]}
openMenuOnFocus={false}
options={
Array [
Object {
"description": "Is team member",
"label": "Member",
"value": 0,
},
Object {
"description": "Can add/remove permissions and delete team.",
"label": "Admin",
"value": 4,
},
]
}
value={
Object {
"description": "Is team member",
"label": "Member",
"value": 0,
}
}
width={null}
/>
</div>
</td>
<td>
<TagBadge
count={0}
key="label 1"
......@@ -474,6 +777,48 @@ exports[`Render should render team members when sync enabled 1`] = `
test@test.com
</td>
<td>
<div
className="gf-form"
>
<Select
autoFocus={false}
backspaceRemovesValue={true}
className="gf-form-select-box__control--menu-right"
isClearable={false}
isDisabled={true}
isLoading={false}
isMulti={false}
isSearchable={false}
maxMenuHeight={300}
onChange={[Function]}
openMenuOnFocus={false}
options={
Array [
Object {
"description": "Is team member",
"label": "Member",
"value": 0,
},
Object {
"description": "Can add/remove permissions and delete team.",
"label": "Admin",
"value": 4,
},
]
}
value={
Object {
"description": "Is team member",
"label": "Member",
"value": 0,
}
}
width={null}
/>
</div>
</td>
<td>
<TagBadge
count={0}
key="label 1"
......@@ -515,6 +860,48 @@ exports[`Render should render team members when sync enabled 1`] = `
test@test.com
</td>
<td>
<div
className="gf-form"
>
<Select
autoFocus={false}
backspaceRemovesValue={true}
className="gf-form-select-box__control--menu-right"
isClearable={false}
isDisabled={true}
isLoading={false}
isMulti={false}
isSearchable={false}
maxMenuHeight={300}
onChange={[Function]}
openMenuOnFocus={false}
options={
Array [
Object {
"description": "Is team member",
"label": "Member",
"value": 0,
},
Object {
"description": "Can add/remove permissions and delete team.",
"label": "Admin",
"value": 4,
},
]
}
value={
Object {
"description": "Is team member",
"label": "Member",
"value": 0,
}
}
width={null}
/>
</div>
</td>
<td>
<TagBadge
count={0}
key="label 1"
......@@ -556,6 +943,48 @@ exports[`Render should render team members when sync enabled 1`] = `
test@test.com
</td>
<td>
<div
className="gf-form"
>
<Select
autoFocus={false}
backspaceRemovesValue={true}
className="gf-form-select-box__control--menu-right"
isClearable={false}
isDisabled={true}
isLoading={false}
isMulti={false}
isSearchable={false}
maxMenuHeight={300}
onChange={[Function]}
openMenuOnFocus={false}
options={
Array [
Object {
"description": "Is team member",
"label": "Member",
"value": 0,
},
Object {
"description": "Can add/remove permissions and delete team.",
"label": "Admin",
"value": 4,
},
]
}
value={
Object {
"description": "Is team member",
"label": "Member",
"value": 0,
}
}
width={null}
/>
</div>
</td>
<td>
<TagBadge
count={0}
key="label 1"
......
......@@ -98,3 +98,23 @@ export const dashboardPermissionLevels: DashboardPermissionInfo[] = [
description: 'Can add/remove permissions and can add, edit and delete dashboards.',
},
];
export enum TeamPermissionLevel {
Member = 0,
Admin = 4,
}
export interface TeamPermissionInfo {
value: TeamPermissionLevel;
label: string;
description: string;
}
export const teamsPermissionLevels: TeamPermissionInfo[] = [
{ value: TeamPermissionLevel.Member, label: 'Member', description: 'Is team member' },
{
value: TeamPermissionLevel.Admin,
label: 'Admin',
description: 'Can add/remove permissions and delete team.',
},
];
......@@ -13,6 +13,7 @@ export interface TeamMember {
email: string;
login: string;
labels: string[];
permission: number;
}
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