Feature Highlights: update upgrade components UI (#47885)

* Highlights: add action prop

* Highlight team sync for trial users

* Add badges for trial highlights

* Move events to UpgradeBox

* Fix undefined license settings

* Update snapshot

* Update public/app/features/datasources/state/navModel.ts

Co-authored-by: Agnès Toulet <35176601+AgnesToulet@users.noreply.github.com>

* Update public/app/features/datasources/state/navModel.ts

Co-authored-by: Agnès Toulet <35176601+AgnesToulet@users.noreply.github.com>

* Update public/app/features/datasources/state/navModel.ts

Co-authored-by: Agnès Toulet <35176601+AgnesToulet@users.noreply.github.com>

* Update copy and event handling

Co-authored-by: Agnès Toulet <35176601+AgnesToulet@users.noreply.github.com>
This commit is contained in:
Alex Khomenko
2022-04-20 15:08:49 +03:00
committed by GitHub
co-authored by Agnès Toulet
parent 68aac0bd90
commit 9c0aa09a85
8 changed files with 144 additions and 62 deletions
+54 -19
View File
@@ -2,7 +2,7 @@ import React, { PureComponent } from 'react';
import { connect, ConnectedProps } from 'react-redux';
import { SlideDown } from 'app/core/components/Animations/SlideDown';
import { LegacyForms, Tooltip, Icon, Button } from '@grafana/ui';
import { LegacyForms, Tooltip, Icon, Button, useTheme2 } from '@grafana/ui';
const { Input } = LegacyForms;
import { StoreState, TeamGroup } from '../../types';
@@ -10,6 +10,8 @@ import { addTeamGroup, loadTeamGroups, removeTeamGroup } from './state/actions';
import { getTeamGroups } from './state/selectors';
import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA';
import { CloseButton } from 'app/core/components/CloseButton/CloseButton';
import { UpgradeBox, UpgradeContent, UpgradeContentProps } from 'app/core/components/Upgrade/UpgradeBox';
import { highlightTrial } from 'app/features/admin/utils';
function mapStateToProps(state: StoreState) {
return {
@@ -90,14 +92,25 @@ export class TeamGroupSync extends PureComponent<Props, State> {
render() {
const { isAdding, newGroupId } = this.state;
const { groups, isReadOnly } = this.props;
return (
<div>
{highlightTrial() && (
<UpgradeBox
featureId={'team-sync'}
eventVariant={'trial'}
featureName={'team sync'}
text={'Add a group to enable team sync for free during your trial of Grafana Pro.'}
/>
)}
<div className="page-action-bar">
<h3 className="page-sub-heading">External group sync</h3>
<Tooltip placement="auto" content={headerTooltip}>
<Icon className="icon--has-hover page-sub-heading-icon" name="question-circle" />
</Tooltip>
{(!highlightTrial() || groups.length > 0) && (
<>
<h3 className="page-sub-heading">External group sync</h3>
<Tooltip placement="auto" content={headerTooltip}>
<Icon className="icon--has-hover page-sub-heading-icon" name="question-circle" />
</Tooltip>
</>
)}
<div className="page-action-bar__spacer" />
{groups.length > 0 && (
<Button className="pull-right" onClick={this.onToggleAdding} disabled={isReadOnly}>
@@ -131,19 +144,23 @@ export class TeamGroupSync extends PureComponent<Props, State> {
</div>
</SlideDown>
{groups.length === 0 && !isAdding && (
<EmptyListCTA
onClick={this.onToggleAdding}
buttonIcon="users-alt"
title="There are no external groups to sync with"
buttonTitle="Add Group"
proTip={headerTooltip}
proTipLinkTitle="Learn more"
proTipLink="http://docs.grafana.org/auth/enhanced_ldap/"
proTipTarget="_blank"
buttonDisabled={isReadOnly}
/>
)}
{groups.length === 0 &&
!isAdding &&
(highlightTrial() ? (
<TeamSyncUpgradeContent action={{ onClick: this.onToggleAdding, text: 'Add group' }} />
) : (
<EmptyListCTA
onClick={this.onToggleAdding}
buttonIcon="users-alt"
title="There are no external groups to sync with"
buttonTitle="Add group"
proTip={headerTooltip}
proTipLinkTitle="Learn more"
proTipLink="https://docs.grafana.org/auth/enhanced_ldap/"
proTipTarget="_blank"
buttonDisabled={isReadOnly}
/>
))}
{groups.length > 0 && (
<div className="admin-list-table">
@@ -163,4 +180,22 @@ export class TeamGroupSync extends PureComponent<Props, State> {
}
}
export const TeamSyncUpgradeContent = ({ action }: { action?: UpgradeContentProps['action'] }) => {
const theme = useTheme2();
return (
<UpgradeContent
action={action}
listItems={[
'Stop managing user access in two places - assign users to groups in SAML, LDAP or Oauth, and manage access at a Team level in Grafana',
'Update users permissions immediately when you add or remove them from an LDAP group, with no need for them to sign out and back in',
]}
image={`team-sync-${theme.isLight ? 'light' : 'dark'}.png`}
featureName={'team sync'}
featureUrl={'https://grafana.com/docs/grafana/latest/enterprise/team-sync'}
description={
'Team Sync makes it easier for you to manage users access in Grafana, by immediately updating each users Grafana teams and permissions based on their single sign-on group membership, instead of when users sign in.'
}
/>
);
};
export default connect(mapStateToProps, mapDispatchToProps)(TeamGroupSync);
+6 -24
View File
@@ -7,7 +7,7 @@ import Page from 'app/core/components/Page/Page';
import TeamMembers from './TeamMembers';
import TeamPermissions from './TeamPermissions';
import TeamSettings from './TeamSettings';
import TeamGroupSync from './TeamGroupSync';
import TeamGroupSync, { TeamSyncUpgradeContent } from './TeamGroupSync';
import { AccessControlAction, StoreState } from 'app/types';
import { loadTeam, loadTeamMembers } from './state/actions';
import { getTeam, getTeamMembers, isSignedInUserTeamAdmin } from './state/selectors';
@@ -15,9 +15,9 @@ import { getTeamLoadingNav } from './state/navModel';
import { getNavModel } from 'app/core/selectors/navModel';
import { contextSrv } from 'app/core/services/context_srv';
import { NavModel } from '@grafana/data';
import { featureEnabled, reportExperimentView } from '@grafana/runtime';
import { featureEnabled } from '@grafana/runtime';
import { GrafanaRouteComponentProps } from 'app/core/navigation/types';
import { UpgradeBox, UpgradeContent } from 'app/core/components/Upgrade/UpgradeBox';
import { UpgradeBox } from 'app/core/components/Upgrade/UpgradeBox';
interface TeamPageRouteParams {
id: string;
@@ -84,13 +84,6 @@ export class TeamPages extends PureComponent<Props, State> {
async componentDidMount() {
await this.fetchTeam();
const { isSyncEnabled } = this.state;
const currentPage = this.getCurrentPage();
if (currentPage === PageTypes.GroupSync && !isSyncEnabled && config.featureToggles.featureHighlights) {
reportExperimentView('feature-highlights-team-sync', 'test', '');
}
}
async fetchTeam() {
@@ -141,7 +134,7 @@ export class TeamPages extends PureComponent<Props, State> {
renderPage(isSignedInUserTeamAdmin: boolean): React.ReactNode {
const { isSyncEnabled } = this.state;
const { members, team, theme } = this.props;
const { members, team } = this.props;
const currentPage = this.getCurrentPage();
const canReadTeam = contextSrv.hasAccessInMetadata(
@@ -177,19 +170,8 @@ export class TeamPages extends PureComponent<Props, State> {
} else if (config.featureToggles.featureHighlights) {
return (
<>
<UpgradeBox featureName={'team sync'} />
<UpgradeContent
listItems={[
'Stop managing user access in two places - assign users to groups in SAML, LDAP or Oauth, and manage access at a Team level in Grafana',
'Update users permissions immediately when you add or remove them from an LDAP group, with no need for them to sign out and back in',
]}
image={`team-sync-${theme.isLight ? 'light' : 'dark'}.png`}
featureName={'team sync'}
featureUrl={'https://grafana.com/docs/grafana/latest/enterprise/team-sync'}
description={
'Team Sync makes it easier for you to manage users access in Grafana, by immediately updating each users Grafana teams and permissions based on their single sign-on group membership, instead of when users sign in.'
}
/>
<UpgradeBox featureName={'team sync'} featureId={'team-sync'} />
<TeamSyncUpgradeContent />
</>
);
}
@@ -67,10 +67,10 @@ exports[`Render should render component 1`] = `
<EmptyListCTA
buttonDisabled={false}
buttonIcon="users-alt"
buttonTitle="Add Group"
buttonTitle="Add group"
onClick={[Function]}
proTip="Sync LDAP or OAuth groups with your Grafana teams."
proTipLink="http://docs.grafana.org/auth/enhanced_ldap/"
proTipLink="https://docs.grafana.org/auth/enhanced_ldap/"
proTipLinkTitle="Learn more"
proTipTarget="_blank"
title="There are no external groups to sync with"
+7 -1
View File
@@ -4,6 +4,7 @@ import { NavModelItem, NavModel } from '@grafana/data';
import config from 'app/core/config';
import { contextSrv } from 'app/core/services/context_srv';
import { ProBadge } from 'app/core/components/Upgrade/ProBadge';
import { highlightTrial } from 'app/features/admin/utils';
const loadingTeam = {
avatarUrl: 'public/img/user_profile.png',
@@ -51,7 +52,7 @@ export function buildNavModel(team: Team): NavModelItem {
});
}
const teamGroupSync = {
const teamGroupSync: NavModelItem = {
active: false,
icon: 'sync',
id: `team-groupsync-${team.id}`,
@@ -61,6 +62,11 @@ export function buildNavModel(team: Team): NavModelItem {
const isLoadingTeam = team === loadingTeam;
if (highlightTrial()) {
teamGroupSync.tabSuffix = () =>
ProBadge({ experimentId: isLoadingTeam ? '' : 'feature-highlights-team-sync-badge', eventVariant: 'trial' });
}
// With both Legacy and FGAC the tab is protected being featureEnabled
// While team is loading we leave the teamsync tab
// With FGAC the External Group Sync tab is available when user has ActionTeamsPermissionsRead for this team