mirror of
https://github.com/grafana/grafana.git
synced 2025-02-11 16:15:42 -06:00
* creating types, actions, reducer * load teams and store in redux * delete team * set search query action and tests * Teampages page * team members, bug in fetching team * flattened team state, tests for TeamMembers * test for team member selector * team settings * actions for group sync * tests for team groups * removed comment * remove old stores * fix: formating of datasource.go * fix: minor changes to imports * adding debounce and fixing issue in teamlist * refactoring: moving types to their own files
165 lines
4.9 KiB
TypeScript
165 lines
4.9 KiB
TypeScript
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 { 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 {
|
|
isAdding: boolean;
|
|
newGroupId?: string;
|
|
}
|
|
|
|
const headerTooltip = `Sync LDAP or OAuth groups with your Grafana teams.`;
|
|
|
|
export class TeamGroupSync extends PureComponent<Props, State> {
|
|
constructor(props) {
|
|
super(props);
|
|
this.state = { isAdding: false, newGroupId: '' };
|
|
}
|
|
|
|
componentDidMount() {
|
|
this.fetchTeamGroups();
|
|
}
|
|
|
|
async fetchTeamGroups() {
|
|
await this.props.loadTeamGroups();
|
|
}
|
|
|
|
onToggleAdding = () => {
|
|
this.setState({ isAdding: !this.state.isAdding });
|
|
};
|
|
|
|
onNewGroupIdChanged = event => {
|
|
this.setState({ newGroupId: event.target.value });
|
|
};
|
|
|
|
onAddGroup = event => {
|
|
event.preventDefault();
|
|
this.props.addTeamGroup(this.state.newGroupId);
|
|
this.setState({ isAdding: false, newGroupId: '' });
|
|
};
|
|
|
|
onRemoveGroup = (group: TeamGroup) => {
|
|
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.groups;
|
|
|
|
return (
|
|
<div>
|
|
<div className="page-action-bar">
|
|
<h3 className="page-sub-heading">External group sync</h3>
|
|
<Tooltip className="page-sub-heading-icon" placement="auto" content={headerTooltip}>
|
|
<i className="gicon gicon-question gicon--has-hover" />
|
|
</Tooltip>
|
|
<div className="page-action-bar__spacer" />
|
|
{groups.length > 0 && (
|
|
<button className="btn btn-success pull-right" onClick={this.onToggleAdding}>
|
|
<i className="fa fa-plus" /> Add group
|
|
</button>
|
|
)}
|
|
</div>
|
|
|
|
<SlideDown in={isAdding}>
|
|
<div className="cta-form">
|
|
<button className="cta-form__close btn btn-transparent" onClick={this.onToggleAdding}>
|
|
<i className="fa fa-close" />
|
|
</button>
|
|
<h5>Add External Group</h5>
|
|
<form className="gf-form-inline" onSubmit={this.onAddGroup}>
|
|
<div className="gf-form">
|
|
<input
|
|
type="text"
|
|
className="gf-form-input width-30"
|
|
value={newGroupId}
|
|
onChange={this.onNewGroupIdChanged}
|
|
placeholder="cn=ops,ou=groups,dc=grafana,dc=org"
|
|
/>
|
|
</div>
|
|
|
|
<div className="gf-form">
|
|
<button className="btn btn-success gf-form-btn" type="submit" disabled={!this.isNewGroupValid()}>
|
|
Add group
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</SlideDown>
|
|
|
|
{groups.length === 0 &&
|
|
!isAdding && (
|
|
<div className="empty-list-cta">
|
|
<div className="empty-list-cta__title">There are no external groups to sync with</div>
|
|
<button onClick={this.onToggleAdding} className="empty-list-cta__button btn btn-xlarge btn-success">
|
|
<i className="gicon gicon-add-team" />
|
|
Add Group
|
|
</button>
|
|
<div className="empty-list-cta__pro-tip">
|
|
<i className="fa fa-rocket" /> {headerTooltip}
|
|
<a className="text-link empty-list-cta__pro-tip-link" href="asd" target="_blank">
|
|
Learn more
|
|
</a>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{groups.length > 0 && (
|
|
<div className="admin-list-table">
|
|
<table className="filter-table filter-table--hover form-inline">
|
|
<thead>
|
|
<tr>
|
|
<th>External Group ID</th>
|
|
<th style={{ width: '1%' }} />
|
|
</tr>
|
|
</thead>
|
|
<tbody>{groups.map(group => this.renderGroup(group))}</tbody>
|
|
</table>
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|
|
}
|
|
|
|
function mapStateToProps(state) {
|
|
return {
|
|
groups: getTeamGroups(state.team),
|
|
};
|
|
}
|
|
|
|
const mapDispatchToProps = {
|
|
loadTeamGroups,
|
|
addTeamGroup,
|
|
removeTeamGroup,
|
|
};
|
|
|
|
export default connect(mapStateToProps, mapDispatchToProps)(TeamGroupSync);
|