mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
team members, bug in fetching team
This commit is contained in:
parent
05bfc36516
commit
59b3bfd342
@ -1,12 +1,21 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { hot } from 'react-hot-loader';
|
||||
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 { Team, TeamMember } from '../../types';
|
||||
import { loadTeamMembers, addTeamMember, removeTeamMember, setSearchMemberQuery } from './state/actions';
|
||||
import { getSearchMemberQuery, getTeam } from './state/selectors';
|
||||
import { getRouteParamsId } from '../../core/selectors/location';
|
||||
|
||||
interface Props {
|
||||
team: Team;
|
||||
searchMemberQuery: string;
|
||||
loadTeamMembers: typeof loadTeamMembers;
|
||||
addTeamMember: typeof addTeamMember;
|
||||
removeTeamMember: typeof removeTeamMember;
|
||||
setSearchMemberQuery: typeof setSearchMemberQuery;
|
||||
}
|
||||
|
||||
interface State {
|
||||
@ -21,20 +30,29 @@ export class TeamMembers extends PureComponent<Props, State> {
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
// this.props.team.loadMembers();
|
||||
this.props.loadTeamMembers();
|
||||
}
|
||||
|
||||
onSearchQueryChange = evt => {
|
||||
// this.props.team.setSearchQuery(evt.target.value);
|
||||
onSearchQueryChange = event => {
|
||||
this.props.setSearchMemberQuery(event.target.value);
|
||||
};
|
||||
|
||||
removeMember(member: TeamMember) {
|
||||
// this.props.team.removeMember(member);
|
||||
this.props.removeTeamMember(member.userId);
|
||||
}
|
||||
|
||||
removeMemberConfirmed(member: TeamMember) {
|
||||
// this.props.team.removeMember(member);
|
||||
}
|
||||
onToggleAdding = () => {
|
||||
this.setState({ isAdding: !this.state.isAdding });
|
||||
};
|
||||
|
||||
onUserSelected = (user: User) => {
|
||||
this.setState({ newTeamMember: user });
|
||||
};
|
||||
|
||||
onAddUserToTeam = async () => {
|
||||
this.props.addTeamMember(this.state.newTeamMember.id);
|
||||
this.setState({ newTeamMember: null });
|
||||
};
|
||||
|
||||
renderMember(member: TeamMember) {
|
||||
return (
|
||||
@ -51,23 +69,9 @@ export class TeamMembers extends PureComponent<Props, State> {
|
||||
);
|
||||
}
|
||||
|
||||
onToggleAdding = () => {
|
||||
this.setState({ isAdding: !this.state.isAdding });
|
||||
};
|
||||
|
||||
onUserSelected = (user: User) => {
|
||||
this.setState({ newTeamMember: user });
|
||||
};
|
||||
|
||||
onAddUserToTeam = async () => {
|
||||
// await this.props.team.addMember(this.state.newTeamMember.id);
|
||||
// await this.props.team.loadMembers();
|
||||
// this.setState({ newTeamMember: null });
|
||||
};
|
||||
|
||||
render() {
|
||||
const { newTeamMember, isAdding } = this.state;
|
||||
const { team } = this.props;
|
||||
const { team, searchMemberQuery } = this.props;
|
||||
const newTeamMemberValue = newTeamMember && newTeamMember.id.toString();
|
||||
|
||||
return (
|
||||
@ -79,7 +83,7 @@ export class TeamMembers extends PureComponent<Props, State> {
|
||||
type="text"
|
||||
className="gf-form-input"
|
||||
placeholder="Search members"
|
||||
value={team.search}
|
||||
value={searchMemberQuery}
|
||||
onChange={this.onSearchQueryChange}
|
||||
/>
|
||||
<i className="gf-form-input-icon fa fa-search" />
|
||||
@ -129,4 +133,20 @@ export class TeamMembers extends PureComponent<Props, State> {
|
||||
}
|
||||
}
|
||||
|
||||
export default hot(module)(TeamMembers);
|
||||
function mapStateToProps(state) {
|
||||
const teamId = getRouteParamsId(state.location);
|
||||
|
||||
return {
|
||||
team: getTeam(state.team, teamId),
|
||||
searchMemberQuery: getSearchMemberQuery(state.team),
|
||||
};
|
||||
}
|
||||
|
||||
const mapDispatchToProps = {
|
||||
loadTeamMembers,
|
||||
addTeamMember,
|
||||
removeTeamMember,
|
||||
setSearchMemberQuery,
|
||||
};
|
||||
|
||||
export default hot(module)(connect(mapStateToProps, mapDispatchToProps)(TeamMembers));
|
||||
|
@ -63,7 +63,7 @@ export class TeamPages extends PureComponent<Props, State> {
|
||||
|
||||
switch (currentPage) {
|
||||
case PageTypes.Members:
|
||||
return <TeamMembers team={team} />;
|
||||
return <TeamMembers />;
|
||||
|
||||
case PageTypes.Settings:
|
||||
return <TeamSettings team={team} />;
|
||||
@ -95,7 +95,7 @@ function mapStateToProps(state) {
|
||||
navModel: getNavModel(state.navIndex, `team-${pageName}-${teamId}`),
|
||||
teamId: teamId,
|
||||
pageName: pageName,
|
||||
team: getTeam(state.team),
|
||||
team: getTeam(state.team, teamId),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -30,3 +30,13 @@ export const getMockTeam = (): Team => {
|
||||
groups: [],
|
||||
};
|
||||
};
|
||||
|
||||
export const getMockTeamMember = () => {
|
||||
return {
|
||||
userId: 1,
|
||||
teamId: 1,
|
||||
avatarUrl: 'some/url/',
|
||||
email: 'test@test.com',
|
||||
login: 'testUser',
|
||||
};
|
||||
};
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { ThunkAction } from 'redux-thunk';
|
||||
import { getBackendSrv } from 'app/core/services/backend_srv';
|
||||
import { NavModelItem, StoreState, Team } from '../../../types';
|
||||
import { NavModelItem, StoreState, Team, TeamMember } from '../../../types';
|
||||
import { updateNavIndex } from '../../../core/actions';
|
||||
import { UpdateNavIndexAction } from '../../../core/actions/navModel';
|
||||
|
||||
@ -8,6 +8,8 @@ export enum ActionTypes {
|
||||
LoadTeams = 'LOAD_TEAMS',
|
||||
LoadTeam = 'LOAD_TEAM',
|
||||
SetSearchQuery = 'SET_SEARCH_QUERY',
|
||||
SetSearchMemberQuery = 'SET_SEARCH_MEMBER_QUERY',
|
||||
LoadTeamMembers = 'TEAM_MEMBERS_LOADED',
|
||||
}
|
||||
|
||||
export interface LoadTeamsAction {
|
||||
@ -20,12 +22,27 @@ export interface LoadTeamAction {
|
||||
payload: Team;
|
||||
}
|
||||
|
||||
export interface LoadTeamMembersAction {
|
||||
type: ActionTypes.LoadTeamMembers;
|
||||
payload: TeamMember[];
|
||||
}
|
||||
|
||||
export interface SetSearchQueryAction {
|
||||
type: ActionTypes.SetSearchQuery;
|
||||
payload: string;
|
||||
}
|
||||
|
||||
export type Action = LoadTeamsAction | SetSearchQueryAction | LoadTeamAction;
|
||||
export interface SetSearchMemberQueryAction {
|
||||
type: ActionTypes.SetSearchMemberQuery;
|
||||
payload: string;
|
||||
}
|
||||
|
||||
export type Action =
|
||||
| LoadTeamsAction
|
||||
| SetSearchQueryAction
|
||||
| LoadTeamAction
|
||||
| LoadTeamMembersAction
|
||||
| SetSearchMemberQueryAction;
|
||||
|
||||
type ThunkResult<R> = ThunkAction<R, StoreState, undefined, Action | UpdateNavIndexAction>;
|
||||
|
||||
@ -39,6 +56,16 @@ const teamLoaded = (team: Team): LoadTeamAction => ({
|
||||
payload: team,
|
||||
});
|
||||
|
||||
const teamMembersLoaded = (teamMembers: TeamMember[]): LoadTeamMembersAction => ({
|
||||
type: ActionTypes.LoadTeamMembers,
|
||||
payload: teamMembers,
|
||||
});
|
||||
|
||||
export const setSearchMemberQuery = (searchQuery: string): SetSearchMemberQueryAction => ({
|
||||
type: ActionTypes.SetSearchMemberQuery,
|
||||
payload: searchQuery,
|
||||
});
|
||||
|
||||
export const setSearchQuery = (searchQuery: string): SetSearchQueryAction => ({
|
||||
type: ActionTypes.SetSearchQuery,
|
||||
payload: searchQuery,
|
||||
@ -89,6 +116,42 @@ export function loadTeam(id: number): ThunkResult<void> {
|
||||
};
|
||||
}
|
||||
|
||||
export function loadTeamMembers(): ThunkResult<void> {
|
||||
return async (dispatch, getStore) => {
|
||||
const team = getStore().team.team;
|
||||
|
||||
await getBackendSrv()
|
||||
.get(`/api/teams/${team.id}/members`)
|
||||
.then(response => {
|
||||
dispatch(teamMembersLoaded(response));
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
export function addTeamMember(id: number): ThunkResult<void> {
|
||||
return async (dispatch, getStore) => {
|
||||
const team = getStore().team.team;
|
||||
|
||||
await getBackendSrv()
|
||||
.post(`/api/teams/${team.id}/members`, { userId: id })
|
||||
.then(() => {
|
||||
dispatch(loadTeamMembers());
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
export function removeTeamMember(id: number): ThunkResult<void> {
|
||||
return async (dispatch, getStore) => {
|
||||
const team = getStore().team.team;
|
||||
|
||||
await getBackendSrv()
|
||||
.delete(`/api/teams/${team.id}/members/${id}`)
|
||||
.then(() => {
|
||||
dispatch(loadTeamMembers());
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
export function deleteTeam(id: number): ThunkResult<void> {
|
||||
return async dispatch => {
|
||||
await getBackendSrv()
|
||||
|
@ -1,20 +1,10 @@
|
||||
import { Action, ActionTypes } from './actions';
|
||||
import { initialTeamsState, teamsReducer } from './reducers';
|
||||
import { initialTeamsState, initialTeamState, teamReducer, teamsReducer } from './reducers';
|
||||
import { getMockTeam, getMockTeamMember } from '../__mocks__/teamMocks';
|
||||
|
||||
describe('teams reducer', () => {
|
||||
it('should set teams', () => {
|
||||
const payload = [
|
||||
{
|
||||
id: 1,
|
||||
name: 'test',
|
||||
avatarUrl: 'some/url/',
|
||||
email: 'test@test.com',
|
||||
memberCount: 1,
|
||||
search: '',
|
||||
members: [],
|
||||
groups: [],
|
||||
},
|
||||
];
|
||||
const payload = [getMockTeam()];
|
||||
|
||||
const action: Action = {
|
||||
type: ActionTypes.LoadTeams,
|
||||
@ -39,3 +29,24 @@ describe('teams reducer', () => {
|
||||
expect(result.searchQuery).toEqual('test');
|
||||
});
|
||||
});
|
||||
|
||||
describe('team reducer', () => {
|
||||
it('should set team members', () => {
|
||||
const mockTeamMember = getMockTeamMember();
|
||||
const mockTeam = getMockTeam();
|
||||
const state = {
|
||||
...initialTeamState,
|
||||
team: mockTeam,
|
||||
};
|
||||
|
||||
const action: Action = {
|
||||
type: ActionTypes.LoadTeamMembers,
|
||||
payload: [mockTeamMember],
|
||||
};
|
||||
|
||||
const result = teamReducer(state, action);
|
||||
const expectedState = { team: { ...mockTeam, members: [mockTeamMember] }, searchQuery: '' };
|
||||
|
||||
expect(result).toEqual(expectedState);
|
||||
});
|
||||
});
|
||||
|
@ -2,7 +2,7 @@ import { Team, TeamsState, TeamState } from '../../../types';
|
||||
import { Action, ActionTypes } from './actions';
|
||||
|
||||
export const initialTeamsState: TeamsState = { teams: [], searchQuery: '' };
|
||||
export const initialTeamState: TeamState = { team: {} as Team, searchQuery: '' };
|
||||
export const initialTeamState: TeamState = { team: {} as Team, searchMemberQuery: '' };
|
||||
|
||||
export const teamsReducer = (state = initialTeamsState, action: Action): TeamsState => {
|
||||
switch (action.type) {
|
||||
@ -19,6 +19,12 @@ export const teamReducer = (state = initialTeamState, action: Action): TeamState
|
||||
switch (action.type) {
|
||||
case ActionTypes.LoadTeam:
|
||||
return { ...state, team: action.payload };
|
||||
|
||||
case ActionTypes.LoadTeamMembers:
|
||||
return { ...state, team: { ...state.team, members: action.payload } };
|
||||
|
||||
case ActionTypes.SetSearchMemberQuery:
|
||||
return { ...state, searchMemberQuery: action.payload };
|
||||
}
|
||||
|
||||
return state;
|
||||
|
@ -1,6 +1,12 @@
|
||||
export const getSearchQuery = state => state.searchQuery;
|
||||
export const getSearchMemberQuery = state => state.searchMemberQuery;
|
||||
|
||||
export const getTeam = state => state.team;
|
||||
export const getTeam = (state, currentTeamId) => {
|
||||
if (state.team.id === currentTeamId) {
|
||||
console.log('yes');
|
||||
return state.team;
|
||||
}
|
||||
};
|
||||
|
||||
export const getTeams = state => {
|
||||
const regex = RegExp(state.searchQuery, 'i');
|
||||
|
@ -124,7 +124,7 @@ export interface TeamsState {
|
||||
|
||||
export interface TeamState {
|
||||
team: Team;
|
||||
searchQuery: string;
|
||||
searchMemberQuery: string;
|
||||
}
|
||||
|
||||
export interface StoreState {
|
||||
@ -132,4 +132,5 @@ export interface StoreState {
|
||||
location: LocationState;
|
||||
alertRules: AlertRulesState;
|
||||
teams: TeamsState;
|
||||
team: TeamState;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user