import { includes } from 'lodash'; import React, { PureComponent } from 'react'; import { connect, ConnectedProps } from 'react-redux'; import { featureEnabled } from '@grafana/runtime'; import { Themeable2, withTheme2 } from '@grafana/ui'; import { Page } from 'app/core/components/Page/Page'; import { UpgradeBox } from 'app/core/components/Upgrade/UpgradeBox'; import config from 'app/core/config'; import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; import { getNavModel } from 'app/core/selectors/navModel'; import { contextSrv } from 'app/core/services/context_srv'; import { AccessControlAction, StoreState } from 'app/types'; import TeamGroupSync, { TeamSyncUpgradeContent } from './TeamGroupSync'; import TeamPermissions from './TeamPermissions'; import TeamSettings from './TeamSettings'; import { loadTeam } from './state/actions'; import { getTeamLoadingNav } from './state/navModel'; import { getTeam } from './state/selectors'; interface TeamPageRouteParams { id: string; page: string | null; } export interface OwnProps extends GrafanaRouteComponentProps, Themeable2 {} interface State { isSyncEnabled: boolean; isLoading: boolean; } enum PageTypes { Members = 'members', Settings = 'settings', GroupSync = 'groupsync', } function mapStateToProps(state: StoreState, props: OwnProps) { const teamId = parseInt(props.match.params.id, 10); const team = getTeam(state.team, teamId); let defaultPage = 'members'; // With RBAC the settings page will always be available if (!team || !contextSrv.hasPermissionInMetadata(AccessControlAction.ActionTeamsPermissionsRead, team)) { defaultPage = 'settings'; } const pageName = props.match.params.page ?? defaultPage; const teamLoadingNav = getTeamLoadingNav(pageName); const pageNav = getNavModel(state.navIndex, `team-${pageName}-${teamId}`, teamLoadingNav).main; return { pageNav, teamId: teamId, pageName: pageName, team, }; } const mapDispatchToProps = { loadTeam, }; const connector = connect(mapStateToProps, mapDispatchToProps); export type Props = OwnProps & ConnectedProps; export class TeamPages extends PureComponent { constructor(props: Props) { super(props); this.state = { isLoading: false, isSyncEnabled: featureEnabled('teamsync'), }; } async componentDidMount() { await this.fetchTeam(); } async fetchTeam() { const { loadTeam, teamId } = this.props; this.setState({ isLoading: true }); const team = await loadTeam(teamId); this.setState({ isLoading: false }); return team; } getCurrentPage() { const pages = ['members', 'settings', 'groupsync']; const currentPage = this.props.pageName; return includes(pages, currentPage) ? currentPage : pages[0]; } textsAreEqual = (text1: string, text2: string) => { if (!text1 && !text2) { return true; } if (!text1 || !text2) { return false; } return text1.toLocaleLowerCase() === text2.toLocaleLowerCase(); }; renderPage(): React.ReactNode { const { isSyncEnabled } = this.state; const { team } = this.props; const currentPage = this.getCurrentPage(); const canReadTeam = contextSrv.hasPermissionInMetadata(AccessControlAction.ActionTeamsRead, team!); const canReadTeamPermissions = contextSrv.hasPermissionInMetadata( AccessControlAction.ActionTeamsPermissionsRead, team! ); const canWriteTeamPermissions = contextSrv.hasPermissionInMetadata( AccessControlAction.ActionTeamsPermissionsWrite, team! ); switch (currentPage) { case PageTypes.Members: if (canReadTeamPermissions) { return ; } case PageTypes.Settings: return canReadTeam && ; case PageTypes.GroupSync: if (isSyncEnabled) { if (canReadTeamPermissions) { return ; } } else if (config.featureToggles.featureHighlights) { return ( <> ); } } return null; } render() { const { team, pageNav } = this.props; return ( {team && Object.keys(team).length !== 0 && this.renderPage()} ); } } export default connector(withTheme2(TeamPages));