Commit 0cfcf268 by Peter Holmberg

actions for group sync

parent b1fe0c4c
import React from 'react';
import { hot } from 'react-hot-loader';
import React, { PureComponent } from 'react';
import { connect } from 'react-redux';
import SlideDown from 'app/core/components/Animations/SlideDown';
import Tooltip from 'app/core/components/Tooltip/Tooltip';
import { Team, TeamGroup } from '../../types';
interface Props {
team: Team;
import { TeamGroup } from '../../types';
import { addTeamGroup, loadTeamGroups, removeTeamGroup } from './state/actions';
import { getTeamGroups } from './state/selectors';
export interface Props {
groups: TeamGroup[];
loadTeamGroups: typeof loadTeamGroups;
addTeamGroup: typeof addTeamGroup;
removeTeamGroup: typeof removeTeamGroup;
}
interface State {
......@@ -15,27 +20,18 @@ interface State {
const headerTooltip = `Sync LDAP or OAuth groups with your Grafana teams.`;
export class TeamGroupSync extends React.Component<Props, State> {
export class TeamGroupSync extends PureComponent<Props, State> {
constructor(props) {
super(props);
this.state = { isAdding: false, newGroupId: '' };
}
componentDidMount() {
// this.props.team.loadGroups();
this.fetchTeamGroups();
}
renderGroup(group: TeamGroup) {
return (
<tr key={group.groupId}>
<td>{group.groupId}</td>
<td style={{ width: '1%' }}>
<a className="btn btn-danger btn-mini" onClick={() => this.onRemoveGroup(group)}>
<i className="fa fa-remove" />
</a>
</td>
</tr>
);
async fetchTeamGroups() {
await this.props.loadTeamGroups();
}
onToggleAdding = () => {
......@@ -47,21 +43,34 @@ export class TeamGroupSync extends React.Component<Props, State> {
};
onAddGroup = () => {
// this.props.team.addGroup(this.state.newGroupId);
this.props.addTeamGroup(this.state.newGroupId);
this.setState({ isAdding: false, newGroupId: '' });
};
onRemoveGroup = (group: TeamGroup) => {
// this.props.team.removeGroup(group.groupId);
this.props.removeTeamGroup(group.groupId);
};
isNewGroupValid() {
return this.state.newGroupId.length > 1;
}
renderGroup(group: TeamGroup) {
return (
<tr key={group.groupId}>
<td>{group.groupId}</td>
<td style={{ width: '1%' }}>
<a className="btn btn-danger btn-mini" onClick={() => this.onRemoveGroup(group)}>
<i className="fa fa-remove" />
</a>
</td>
</tr>
);
}
render() {
const { isAdding, newGroupId } = this.state;
const groups = this.props.team.groups;
const groups = this.props.groups;
return (
<div>
......@@ -144,4 +153,16 @@ export class TeamGroupSync extends React.Component<Props, State> {
}
}
export default hot(module)(TeamGroupSync);
function mapStateToProps(state) {
return {
groups: getTeamGroups(state.team),
};
}
const mapDispatchToProps = {
loadTeamGroups,
addTeamGroup,
removeTeamGroup,
};
export default connect(mapStateToProps, mapDispatchToProps)(TeamGroupSync);
......@@ -57,7 +57,6 @@ export class TeamPages extends PureComponent<Props, State> {
}
renderPage() {
const { team } = this.props;
const { isSyncEnabled } = this.state;
const currentPage = this.getCurrentPage();
......@@ -69,7 +68,7 @@ export class TeamPages extends PureComponent<Props, State> {
return <TeamSettings />;
case PageTypes.GroupSync:
return isSyncEnabled && <TeamGroupSync team={team} />;
return isSyncEnabled && <TeamGroupSync />;
}
return null;
......
import { ThunkAction } from 'redux-thunk';
import { getBackendSrv } from 'app/core/services/backend_srv';
import { NavModelItem, StoreState, Team, TeamMember } from '../../../types';
import { NavModelItem, StoreState, Team, TeamGroup, TeamMember } from '../../../types';
import { updateNavIndex } from '../../../core/actions';
import { UpdateNavIndexAction } from '../../../core/actions/navModel';
import config from 'app/core/config';
export enum ActionTypes {
LoadTeams = 'LOAD_TEAMS',
......@@ -10,6 +11,7 @@ export enum ActionTypes {
SetSearchQuery = 'SET_SEARCH_QUERY',
SetSearchMemberQuery = 'SET_SEARCH_MEMBER_QUERY',
LoadTeamMembers = 'TEAM_MEMBERS_LOADED',
LoadTeamGroups = 'TEAM_GROUPS_LOADED',
}
export interface LoadTeamsAction {
......@@ -27,6 +29,11 @@ export interface LoadTeamMembersAction {
payload: TeamMember[];
}
export interface LoadTeamGroupsAction {
type: ActionTypes.LoadTeamGroups;
payload: TeamGroup[];
}
export interface SetSearchQueryAction {
type: ActionTypes.SetSearchQuery;
payload: string;
......@@ -42,7 +49,8 @@ export type Action =
| SetSearchQueryAction
| LoadTeamAction
| LoadTeamMembersAction
| SetSearchMemberQueryAction;
| SetSearchMemberQueryAction
| LoadTeamGroupsAction;
type ThunkResult<R> = ThunkAction<R, StoreState, undefined, Action | UpdateNavIndexAction>;
......@@ -61,6 +69,11 @@ const teamMembersLoaded = (teamMembers: TeamMember[]): LoadTeamMembersAction =>
payload: teamMembers,
});
const teamGroupsLoaded = (teamGroups: TeamGroup[]): LoadTeamGroupsAction => ({
type: ActionTypes.LoadTeamGroups,
payload: teamGroups,
});
export const setSearchMemberQuery = (searchQuery: string): SetSearchMemberQueryAction => ({
type: ActionTypes.SetSearchMemberQuery,
payload: searchQuery,
......@@ -79,7 +92,7 @@ export function loadTeams(): ThunkResult<void> {
}
function buildNavModel(team: Team): NavModelItem {
return {
const navModel = {
img: team.avatarUrl,
id: 'team-' + team.id,
subTitle: 'Manage members & settings',
......@@ -103,6 +116,18 @@ function buildNavModel(team: Team): NavModelItem {
},
],
};
if (config.buildInfo.isEnterprise) {
navModel.children.push({
active: false,
icon: 'fa fa-fw fa-refresh',
id: 'team-settings',
text: 'External group sync',
url: `org/teams/edit/${team.id}/groupsync`,
});
}
return navModel;
}
export function loadTeam(id: number): ThunkResult<void> {
......@@ -117,7 +142,6 @@ export function loadTeam(id: number): ThunkResult<void> {
}
export function loadTeamMembers(): ThunkResult<void> {
console.log('loading team members');
return async (dispatch, getStore) => {
const team = getStore().team.team;
......@@ -167,6 +191,42 @@ export function updateTeam(name: string, email: string): ThunkResult<void> {
};
}
export function loadTeamGroups(): ThunkResult<void> {
return async (dispatch, getStore) => {
const team = getStore().team.team;
await getBackendSrv()
.get(`/api/teams/${team.id}/groups`)
.then(response => {
dispatch(teamGroupsLoaded(response));
});
};
}
export function addTeamGroup(groupId: string): ThunkResult<void> {
return async (dispatch, getStore) => {
const team = getStore().team.team;
await getBackendSrv()
.post(`/api/teams/${team.id}/groups`, { groupId: groupId })
.then(() => {
dispatch(loadTeamGroups());
});
};
}
export function removeTeamGroup(groupId: string): ThunkResult<void> {
return async (dispatch, getStore) => {
const team = getStore().team.team;
await getBackendSrv()
.delete(`/api/teams/${team.id}/groups/${groupId}`)
.then(() => {
dispatch(loadTeamGroups());
});
};
}
export function deleteTeam(id: number): ThunkResult<void> {
return async dispatch => {
await getBackendSrv()
......
......@@ -30,6 +30,9 @@ export const teamReducer = (state = initialTeamState, action: Action): TeamState
case ActionTypes.SetSearchMemberQuery:
return { ...state, searchMemberQuery: action.payload };
case ActionTypes.LoadTeamGroups:
return { ...state, groups: action.payload };
}
return state;
......
export const getSearchQuery = state => state.searchQuery;
export const getSearchMemberQuery = state => state.searchMemberQuery;
export const getTeamGroups = state => state.groups;
export const getTeam = (state, currentTeamId) => {
if (state.team.id === parseInt(currentTeamId)) {
......
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