Commit 1c365420 by Shavonn Brown Committed by GitHub

convert teams section of user profile to react (#18633)

* convert teams section of user profile to react

* isLoading prop

* loading placeholders
parent e50a75f2
import React, { PureComponent } from 'react'; import React, { PureComponent } from 'react';
import { getBackendSrv } from '@grafana/runtime'; import { getBackendSrv } from '@grafana/runtime';
import { User } from 'app/types'; import { User, Team } from 'app/types';
export interface UserAPI { export interface UserAPI {
changePassword: (changePassword: ChangePasswordFields) => void; changePassword: (changePassword: ChangePasswordFields) => void;
updateUserProfile: (profile: ProfileUpdateFields) => void; updateUserProfile: (profile: ProfileUpdateFields) => void;
loadUser: () => void; loadUser: () => void;
loadTeams: () => void;
} }
interface LoadingStates { interface LoadingStates {
changePassword: boolean; changePassword: boolean;
loadUser: boolean; loadUser: boolean;
loadTeams: boolean;
updateUserProfile: boolean; updateUserProfile: boolean;
} }
...@@ -28,24 +30,27 @@ export interface ProfileUpdateFields { ...@@ -28,24 +30,27 @@ export interface ProfileUpdateFields {
export interface Props { export interface Props {
userId?: number; // passed, will load user on mount 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 { export interface State {
user?: User; user?: User;
teams: Team[];
loadingStates: LoadingStates; loadingStates: LoadingStates;
} }
export class UserProvider extends PureComponent<Props, State> { export class UserProvider extends PureComponent<Props, State> {
state: State = { state: State = {
teams: [] as Team[],
loadingStates: { loadingStates: {
changePassword: false, changePassword: false,
loadUser: true, loadUser: true,
loadTeams: false,
updateUserProfile: false, updateUserProfile: false,
}, },
}; };
componentDidMount() { componentWillMount() {
if (this.props.userId) { if (this.props.userId) {
this.loadUser(); this.loadUser();
} }
...@@ -65,6 +70,14 @@ export class UserProvider extends PureComponent<Props, State> { ...@@ -65,6 +70,14 @@ export class UserProvider extends PureComponent<Props, State> {
this.setState({ user, loadingStates: { ...this.state.loadingStates, loadUser: Object.keys(user).length === 0 } }); 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) => { updateUserProfile = async (payload: ProfileUpdateFields) => {
this.setState({ loadingStates: { ...this.state.loadingStates, updateUserProfile: true } }); this.setState({ loadingStates: { ...this.state.loadingStates, updateUserProfile: true } });
await getBackendSrv() await getBackendSrv()
...@@ -80,15 +93,16 @@ export class UserProvider extends PureComponent<Props, State> { ...@@ -80,15 +93,16 @@ export class UserProvider extends PureComponent<Props, State> {
render() { render() {
const { children } = this.props; const { children } = this.props;
const { loadingStates, user } = this.state; const { loadingStates, teams, user } = this.state;
const api = { const api = {
changePassword: this.changePassword, changePassword: this.changePassword,
loadUser: this.loadUser, loadUser: this.loadUser,
loadTeams: this.loadTeams,
updateUserProfile: this.updateUserProfile, updateUserProfile: this.updateUserProfile,
}; };
return <>{children(api, loadingStates, user)}</>; return <>{children(api, loadingStates, teams, user)}</>;
} }
} }
......
...@@ -7,11 +7,9 @@ import { BackendSrv } from 'app/core/services/backend_srv'; ...@@ -7,11 +7,9 @@ import { BackendSrv } from 'app/core/services/backend_srv';
export class ProfileCtrl { export class ProfileCtrl {
user: any; user: any;
oldTheme: any; oldTheme: any;
teams: any = [];
orgs: any = []; orgs: any = [];
sessions: object[] = []; sessions: object[] = [];
userForm: any; userForm: any;
showTeamsList = false;
showOrgsList = false; showOrgsList = false;
readonlyLoginFields = config.disableLoginForm; readonlyLoginFields = config.disableLoginForm;
navModel: any; navModel: any;
...@@ -19,7 +17,6 @@ export class ProfileCtrl { ...@@ -19,7 +17,6 @@ export class ProfileCtrl {
/** @ngInject */ /** @ngInject */
constructor(private backendSrv: BackendSrv, navModelSrv: NavModelSrv) { constructor(private backendSrv: BackendSrv, navModelSrv: NavModelSrv) {
this.getUserSessions(); this.getUserSessions();
this.getUserTeams();
this.getUserOrgs(); this.getUserOrgs();
this.navModel = navModelSrv.getNav('profile', 'profile-settings', 0); this.navModel = navModelSrv.getNav('profile', 'profile-settings', 0);
} }
...@@ -70,13 +67,6 @@ export class ProfileCtrl { ...@@ -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() { getUserOrgs() {
this.backendSrv.get('/api/user/orgs').then((orgs: any) => { this.backendSrv.get('/api/user/orgs').then((orgs: any) => {
this.orgs = orgs; this.orgs = orgs;
......
...@@ -2,14 +2,18 @@ import React from 'react'; ...@@ -2,14 +2,18 @@ import React from 'react';
import { UserProvider } from 'app/core/utils/UserProvider'; import { UserProvider } from 'app/core/utils/UserProvider';
import { UserProfileEditForm } from './UserProfileEditForm'; import { UserProfileEditForm } from './UserProfileEditForm';
import { SharedPreferences } from 'app/core/components/SharedPreferences/SharedPreferences'; import { SharedPreferences } from 'app/core/components/SharedPreferences/SharedPreferences';
import { UserTeams } from './UserTeams';
import { config } from '@grafana/runtime'; import { config } from '@grafana/runtime';
import { LoadingPlaceholder } from '@grafana/ui';
export const ReactProfileWrapper = () => ( export const ReactProfileWrapper = () => (
<UserProvider userId={config.bootData.user.id}> <UserProvider userId={config.bootData.user.id}>
{(api, states, user) => { {(api, states, teams, user) => {
return ( return (
<> <>
{!states.loadUser && ( {states.loadUser ? (
<LoadingPlaceholder text="Loading user profile..." />
) : (
<UserProfileEditForm <UserProfileEditForm
updateProfile={api.updateUserProfile} updateProfile={api.updateUserProfile}
isSavingUser={states.updateUserProfile} isSavingUser={states.updateUserProfile}
...@@ -17,6 +21,7 @@ export const ReactProfileWrapper = () => ( ...@@ -17,6 +21,7 @@ export const ReactProfileWrapper = () => (
/> />
)} )}
<SharedPreferences resourceUri="user" /> <SharedPreferences resourceUri="user" />
<UserTeams isLoading={states.loadTeams} loadTeams={api.loadTeams} teams={teams} />
</> </>
); );
}} }}
......
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<Props> {
componentDidMount() {
this.props.loadTeams();
}
render() {
const { isLoading, teams } = this.props;
if (isLoading) {
return <LoadingPlaceholder text="Loading teams..." />;
}
return (
<>
{teams.length > 0 && (
<>
<h3 className="page-sub-heading">Teams</h3>
<div className="gf-form-group">
<table className="filter-table form-inline">
<thead>
<tr>
<th />
<th>Name</th>
<th>Email</th>
<th>Members</th>
</tr>
</thead>
<tbody>
{teams.map((team: Team, index) => {
return (
<tr key={index}>
<td className="width-4 text-center">
<img className="filter-table__avatar" src={team.avatarUrl} />
</td>
<td>{team.name}</td>
<td>{team.email}</td>
<td>{team.memberCount}</td>
</tr>
);
})}
</tbody>
</table>
</div>
</>
)}
</>
);
}
}
export default UserTeams;
...@@ -3,28 +3,6 @@ ...@@ -3,28 +3,6 @@
<div class="page-container page-body"> <div class="page-container page-body">
<react-profile-wrapper></react-profile-wrapper> <react-profile-wrapper></react-profile-wrapper>
<h3 class="page-heading" ng-show="ctrl.showTeamsList">Teams</h3>
<div class="gf-form-group" ng-show="ctrl.showTeamsList">
<table class="filter-table form-inline">
<thead>
<tr>
<th></th>
<th>Name</th>
<th>Email</th>
<th>Members</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="team in ctrl.teams">
<td class="width-4 text-center"><img class="filter-table__avatar" ng-src="{{ team.avatarUrl }}" /></td>
<td>{{ team.name }}</td>
<td>{{ team.email }}</td>
<td>{{ team.memberCount }}</td>
</tr>
</tbody>
</table>
</div>
<h3 class="page-heading" ng-show="ctrl.showOrgsList">Organizations</h3> <h3 class="page-heading" ng-show="ctrl.showOrgsList">Organizations</h3>
<div class="gf-form-group" ng-show="ctrl.showOrgsList"> <div class="gf-form-group" ng-show="ctrl.showOrgsList">
<table class="filter-table form-inline"> <table class="filter-table form-inline">
......
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