mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
convert teams section of user profile to react (#18633)
* convert teams section of user profile to react * isLoading prop * loading placeholders
This commit is contained in:
parent
e50a75f25f
commit
1c36542018
@ -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<Props, State> {
|
||||
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<Props, State> {
|
||||
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<Props, State> {
|
||||
|
||||
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)}</>;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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 = () => (
|
||||
<UserProvider userId={config.bootData.user.id}>
|
||||
{(api, states, user) => {
|
||||
{(api, states, teams, user) => {
|
||||
return (
|
||||
<>
|
||||
{!states.loadUser && (
|
||||
{states.loadUser ? (
|
||||
<LoadingPlaceholder text="Loading user profile..." />
|
||||
) : (
|
||||
<UserProfileEditForm
|
||||
updateProfile={api.updateUserProfile}
|
||||
isSavingUser={states.updateUserProfile}
|
||||
@ -17,6 +21,7 @@ export const ReactProfileWrapper = () => (
|
||||
/>
|
||||
)}
|
||||
<SharedPreferences resourceUri="user" />
|
||||
<UserTeams isLoading={states.loadTeams} loadTeams={api.loadTeams} teams={teams} />
|
||||
</>
|
||||
);
|
||||
}}
|
||||
|
61
public/app/features/profile/UserTeams.tsx
Normal file
61
public/app/features/profile/UserTeams.tsx
Normal file
@ -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<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 @@
|
||||
<div class="page-container page-body">
|
||||
<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>
|
||||
<div class="gf-form-group" ng-show="ctrl.showOrgsList">
|
||||
<table class="filter-table form-inline">
|
||||
|
Loading…
Reference in New Issue
Block a user