withTeamsForUser.tsx 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. import {Component} from 'react';
  2. import {Client} from 'sentry/api';
  3. import ConfigStore from 'sentry/stores/configStore';
  4. import {Organization, Project, Team, TeamWithProjects} from 'sentry/types';
  5. import getDisplayName from 'sentry/utils/getDisplayName';
  6. import getProjectsByTeams from 'sentry/utils/getProjectsByTeams';
  7. import {metric} from './analytics';
  8. // We require these props when using this HOC
  9. type DependentProps = {
  10. api: Client;
  11. organization: Organization;
  12. };
  13. type InjectedTeamsProps = {
  14. error: Error | null;
  15. loadingTeams: boolean;
  16. teams: TeamWithProjects[];
  17. };
  18. const withTeamsForUser = <P extends InjectedTeamsProps>(
  19. WrappedComponent: React.ComponentType<P>
  20. ) =>
  21. class extends Component<
  22. Omit<P, keyof InjectedTeamsProps> & Partial<InjectedTeamsProps> & DependentProps,
  23. InjectedTeamsProps
  24. > {
  25. static displayName = `withUsersTeams(${getDisplayName(WrappedComponent)})`;
  26. state: InjectedTeamsProps = {
  27. teams: [],
  28. loadingTeams: true,
  29. error: null,
  30. };
  31. componentDidMount() {
  32. this.fetchTeams();
  33. }
  34. async fetchTeams() {
  35. this.setState({
  36. loadingTeams: true,
  37. });
  38. try {
  39. metric.mark({name: 'user-teams-fetch-start'});
  40. const teamsWithProjects: TeamWithProjects[] = await this.props.api.requestPromise(
  41. this.getUsersTeamsEndpoint()
  42. );
  43. this.setState(
  44. {
  45. teams: teamsWithProjects,
  46. loadingTeams: false,
  47. },
  48. () => {
  49. metric.measure({
  50. name: 'app.component.perf',
  51. start: 'user-teams-fetch-start',
  52. data: {
  53. name: 'user-teams',
  54. route: '/organizations/:orgid/user-teams',
  55. organization_id: parseInt(this.props.organization.id, 10),
  56. },
  57. });
  58. }
  59. );
  60. } catch (error) {
  61. this.setState({
  62. error,
  63. loadingTeams: false,
  64. });
  65. }
  66. }
  67. populateTeamsWithProjects(teams: Team[], projects: Project[]) {
  68. const {isSuperuser} = ConfigStore.get('user');
  69. const {projectsByTeam} = getProjectsByTeams(teams, projects, isSuperuser);
  70. const teamsWithProjects: TeamWithProjects[] = teams.map(team => {
  71. const teamProjects = projectsByTeam[team.slug] || [];
  72. return {...team, projects: teamProjects};
  73. });
  74. this.setState({
  75. teams: teamsWithProjects,
  76. loadingTeams: false,
  77. });
  78. }
  79. getUsersTeamsEndpoint() {
  80. return `/organizations/${this.props.organization.slug}/user-teams/`;
  81. }
  82. render() {
  83. return <WrappedComponent {...(this.props as P & DependentProps)} {...this.state} />;
  84. }
  85. };
  86. export default withTeamsForUser;