diff --git a/public/app/core/utils/UserProvider.tsx b/public/app/core/utils/UserProvider.tsx index bdb06c07910..e1e115c23bb 100644 --- a/public/app/core/utils/UserProvider.tsx +++ b/public/app/core/utils/UserProvider.tsx @@ -1,16 +1,18 @@ import React, { PureComponent } from 'react'; import { getBackendSrv } from '@grafana/runtime'; -import { User } from 'app/types'; +import { User, Team } from 'app/types'; export interface UserAPI { changePassword: (changePassword: ChangePasswordFields) => void; updateUserProfile: (profile: ProfileUpdateFields) => void; loadUser: () => void; + loadTeams: () => void; } interface LoadingStates { changePassword: boolean; loadUser: boolean; + loadTeams: boolean; updateUserProfile: boolean; } @@ -28,24 +30,27 @@ export interface ProfileUpdateFields { export interface Props { userId?: number; // passed, will load user on mount - children: (api: UserAPI, states: LoadingStates, user?: User) => JSX.Element; + children: (api: UserAPI, states: LoadingStates, teams: Team[], user?: User) => JSX.Element; } export interface State { user?: User; + teams: Team[]; loadingStates: LoadingStates; } export class UserProvider extends PureComponent { state: State = { + teams: [] as Team[], loadingStates: { changePassword: false, loadUser: true, + loadTeams: false, updateUserProfile: false, }, }; - componentDidMount() { + componentWillMount() { if (this.props.userId) { this.loadUser(); } @@ -65,6 +70,14 @@ export class UserProvider extends PureComponent { this.setState({ user, loadingStates: { ...this.state.loadingStates, loadUser: Object.keys(user).length === 0 } }); }; + loadTeams = async () => { + this.setState({ + loadingStates: { ...this.state.loadingStates, loadTeams: true }, + }); + const teams = await getBackendSrv().get('/api/user/teams'); + this.setState({ teams, loadingStates: { ...this.state.loadingStates, loadTeams: false } }); + }; + updateUserProfile = async (payload: ProfileUpdateFields) => { this.setState({ loadingStates: { ...this.state.loadingStates, updateUserProfile: true } }); await getBackendSrv() @@ -80,15 +93,16 @@ export class UserProvider extends PureComponent { render() { const { children } = this.props; - const { loadingStates, user } = this.state; + const { loadingStates, teams, user } = this.state; const api = { changePassword: this.changePassword, loadUser: this.loadUser, + loadTeams: this.loadTeams, updateUserProfile: this.updateUserProfile, }; - return <>{children(api, loadingStates, user)}; + return <>{children(api, loadingStates, teams, user)}; } } diff --git a/public/app/features/profile/ProfileCtrl.ts b/public/app/features/profile/ProfileCtrl.ts index d267cd0588b..c604541bb8e 100644 --- a/public/app/features/profile/ProfileCtrl.ts +++ b/public/app/features/profile/ProfileCtrl.ts @@ -7,11 +7,9 @@ import { BackendSrv } from 'app/core/services/backend_srv'; export class ProfileCtrl { user: any; oldTheme: any; - teams: any = []; orgs: any = []; sessions: object[] = []; userForm: any; - showTeamsList = false; showOrgsList = false; readonlyLoginFields = config.disableLoginForm; navModel: any; @@ -19,7 +17,6 @@ export class ProfileCtrl { /** @ngInject */ constructor(private backendSrv: BackendSrv, navModelSrv: NavModelSrv) { this.getUserSessions(); - this.getUserTeams(); this.getUserOrgs(); this.navModel = navModelSrv.getNav('profile', 'profile-settings', 0); } @@ -70,13 +67,6 @@ export class ProfileCtrl { }); } - getUserTeams() { - this.backendSrv.get('/api/user/teams').then((teams: any) => { - this.teams = teams; - this.showTeamsList = this.teams.length > 0; - }); - } - getUserOrgs() { this.backendSrv.get('/api/user/orgs').then((orgs: any) => { this.orgs = orgs; diff --git a/public/app/features/profile/ReactProfileWrapper.tsx b/public/app/features/profile/ReactProfileWrapper.tsx index ab1c6dc7a3d..5330d2c8b41 100644 --- a/public/app/features/profile/ReactProfileWrapper.tsx +++ b/public/app/features/profile/ReactProfileWrapper.tsx @@ -2,14 +2,18 @@ import React from 'react'; import { UserProvider } from 'app/core/utils/UserProvider'; import { UserProfileEditForm } from './UserProfileEditForm'; import { SharedPreferences } from 'app/core/components/SharedPreferences/SharedPreferences'; +import { UserTeams } from './UserTeams'; import { config } from '@grafana/runtime'; +import { LoadingPlaceholder } from '@grafana/ui'; export const ReactProfileWrapper = () => ( - {(api, states, user) => { + {(api, states, teams, user) => { return ( <> - {!states.loadUser && ( + {states.loadUser ? ( + + ) : ( ( /> )} + ); }} diff --git a/public/app/features/profile/UserTeams.tsx b/public/app/features/profile/UserTeams.tsx new file mode 100644 index 00000000000..86ee8112101 --- /dev/null +++ b/public/app/features/profile/UserTeams.tsx @@ -0,0 +1,61 @@ +import React, { PureComponent } from 'react'; +import { Team } from 'app/types'; +import { LoadingPlaceholder } from '@grafana/ui'; + +export interface Props { + teams: Team[]; + isLoading: boolean; + loadTeams: () => void; +} + +export class UserTeams extends PureComponent { + componentDidMount() { + this.props.loadTeams(); + } + + render() { + const { isLoading, teams } = this.props; + + if (isLoading) { + return ; + } + + return ( + <> + {teams.length > 0 && ( + <> +

Teams

+
+ + + + + + + + + + {teams.map((team: Team, index) => { + return ( + + + + + + + ); + })} + +
+ NameEmailMembers
+ + {team.name}{team.email}{team.memberCount}
+
+ + )} + + ); + } +} + +export default UserTeams; diff --git a/public/app/features/profile/partials/profile.html b/public/app/features/profile/partials/profile.html index 9d30a2277f3..a924cdfe2ec 100644 --- a/public/app/features/profile/partials/profile.html +++ b/public/app/features/profile/partials/profile.html @@ -3,28 +3,6 @@
-

Teams

-
- - - - - - - - - - - - - - - - - -
NameEmailMembers
{{ team.name }}{{ team.email }}{{ team.memberCount }}
-
-

Organizations