|
@@ -1,4 +1,4 @@
|
|
|
-import {Component, Fragment} from 'react';
|
|
|
+import {Fragment, useEffect} from 'react';
|
|
|
import LazyLoad from 'react-lazyload';
|
|
|
import {RouteComponentProps} from 'react-router';
|
|
|
import styled from '@emotion/styled';
|
|
@@ -36,101 +36,89 @@ type Props = {
|
|
|
error: Error | null;
|
|
|
} & RouteComponentProps<{orgId: string}, {}>;
|
|
|
|
|
|
-class Dashboard extends Component<Props> {
|
|
|
- componentWillUnmount() {
|
|
|
- ProjectsStatsStore.reset();
|
|
|
- }
|
|
|
-
|
|
|
- render() {
|
|
|
- const {teams, params, organization, loadingTeams, error} = this.props;
|
|
|
-
|
|
|
- if (loadingTeams) {
|
|
|
- return <LoadingIndicator />;
|
|
|
- }
|
|
|
+function Dashboard({teams, params, organization, loadingTeams, error}: Props) {
|
|
|
+ useEffect(() => {
|
|
|
+ return function cleanup() {
|
|
|
+ ProjectsStatsStore.reset();
|
|
|
+ };
|
|
|
+ }, []);
|
|
|
|
|
|
- if (error) {
|
|
|
- return <LoadingError message="An error occurred while fetching your projects" />;
|
|
|
- }
|
|
|
+ if (loadingTeams) {
|
|
|
+ return <LoadingIndicator />;
|
|
|
+ }
|
|
|
|
|
|
- const filteredTeams = teams.filter(team => team.projects.length);
|
|
|
- filteredTeams.sort((team1, team2) => team1.slug.localeCompare(team2.slug));
|
|
|
+ if (error) {
|
|
|
+ return <LoadingError message={t('An error occurred while fetching your projects')} />;
|
|
|
+ }
|
|
|
|
|
|
- const projects = uniqBy(flatten(teams.map(teamObj => teamObj.projects)), 'id');
|
|
|
- const favorites = projects.filter(project => project.isBookmarked);
|
|
|
+ const filteredTeams = teams.filter(team => team.projects.length);
|
|
|
+ filteredTeams.sort((team1, team2) => team1.slug.localeCompare(team2.slug));
|
|
|
|
|
|
- const access = new Set(organization.access);
|
|
|
- const canCreateProjects = access.has('project:admin');
|
|
|
- const hasTeamAdminAccess = access.has('team:admin');
|
|
|
+ const projects = uniqBy(flatten(teams.map(teamObj => teamObj.projects)), 'id');
|
|
|
+ const favorites = projects.filter(project => project.isBookmarked);
|
|
|
|
|
|
- const showEmptyMessage = projects.length === 0 && favorites.length === 0;
|
|
|
- const showResources = projects.length === 1 && !projects[0].firstEvent;
|
|
|
+ const canCreateProjects = organization.access.includes('project:admin');
|
|
|
+ const hasTeamAdminAccess = organization.access.includes('team:admin');
|
|
|
|
|
|
- if (showEmptyMessage) {
|
|
|
- return (
|
|
|
- <NoProjectMessage
|
|
|
- organization={organization}
|
|
|
- projects={projects}
|
|
|
- superuserNeedsToBeProjectMember
|
|
|
- >
|
|
|
- {null}
|
|
|
- </NoProjectMessage>
|
|
|
- );
|
|
|
- }
|
|
|
+ const showEmptyMessage = projects.length === 0 && favorites.length === 0;
|
|
|
+ const showResources = projects.length === 1 && !projects[0].firstEvent;
|
|
|
|
|
|
+ if (showEmptyMessage) {
|
|
|
return (
|
|
|
- <Fragment>
|
|
|
- <SentryDocumentTitle
|
|
|
- title={t('Projects Dashboard')}
|
|
|
- orgSlug={organization.slug}
|
|
|
- />
|
|
|
- {projects.length > 0 && (
|
|
|
- <ProjectsHeader>
|
|
|
- <PageHeading>Projects</PageHeading>
|
|
|
- <Button
|
|
|
- size="small"
|
|
|
- disabled={!canCreateProjects}
|
|
|
- title={
|
|
|
- !canCreateProjects
|
|
|
- ? t('You do not have permission to create projects')
|
|
|
- : undefined
|
|
|
- }
|
|
|
- to={`/organizations/${organization.slug}/projects/new/`}
|
|
|
- icon={<IconAdd size="xs" isCircled />}
|
|
|
- data-test-id="create-project"
|
|
|
- >
|
|
|
- {t('Create Project')}
|
|
|
- </Button>
|
|
|
- </ProjectsHeader>
|
|
|
- )}
|
|
|
-
|
|
|
- {filteredTeams.map((team, index) => {
|
|
|
- const showBorder = index !== teams.length - 1;
|
|
|
- return (
|
|
|
- <LazyLoad key={team.slug} once debounce={50} height={300} offset={300}>
|
|
|
- <TeamSection
|
|
|
- orgId={params.orgId}
|
|
|
- team={team}
|
|
|
- showBorder={showBorder}
|
|
|
- title={
|
|
|
- hasTeamAdminAccess ? (
|
|
|
- <TeamLink to={`/settings/${organization.slug}/teams/${team.slug}/`}>
|
|
|
- <IdBadge team={team} avatarSize={22} />
|
|
|
- </TeamLink>
|
|
|
- ) : (
|
|
|
- <IdBadge team={team} avatarSize={22} />
|
|
|
- )
|
|
|
- }
|
|
|
- projects={sortProjects(team.projects)}
|
|
|
- access={access}
|
|
|
- />
|
|
|
- </LazyLoad>
|
|
|
- );
|
|
|
- })}
|
|
|
-
|
|
|
- {showResources && <Resources organization={organization} />}
|
|
|
- </Fragment>
|
|
|
+ <NoProjectMessage
|
|
|
+ organization={organization}
|
|
|
+ projects={projects}
|
|
|
+ superuserNeedsToBeProjectMember
|
|
|
+ />
|
|
|
);
|
|
|
}
|
|
|
+
|
|
|
+ return (
|
|
|
+ <Fragment>
|
|
|
+ <SentryDocumentTitle title={t('Projects Dashboard')} orgSlug={organization.slug} />
|
|
|
+ {projects.length > 0 && (
|
|
|
+ <ProjectsHeader>
|
|
|
+ <PageHeading>{t('Projects')}</PageHeading>
|
|
|
+ <Button
|
|
|
+ size="small"
|
|
|
+ disabled={!canCreateProjects}
|
|
|
+ title={
|
|
|
+ !canCreateProjects
|
|
|
+ ? t('You do not have permission to create projects')
|
|
|
+ : undefined
|
|
|
+ }
|
|
|
+ to={`/organizations/${organization.slug}/projects/new/`}
|
|
|
+ icon={<IconAdd size="xs" isCircled />}
|
|
|
+ data-test-id="create-project"
|
|
|
+ >
|
|
|
+ {t('Create Project')}
|
|
|
+ </Button>
|
|
|
+ </ProjectsHeader>
|
|
|
+ )}
|
|
|
+
|
|
|
+ {filteredTeams.map((team, index) => (
|
|
|
+ <LazyLoad key={team.slug} once debounce={50} height={300} offset={300}>
|
|
|
+ <TeamSection
|
|
|
+ orgId={params.orgId}
|
|
|
+ team={team}
|
|
|
+ showBorder={index !== teams.length - 1}
|
|
|
+ title={
|
|
|
+ hasTeamAdminAccess ? (
|
|
|
+ <TeamLink to={`/settings/${organization.slug}/teams/${team.slug}/`}>
|
|
|
+ <IdBadge team={team} avatarSize={22} />
|
|
|
+ </TeamLink>
|
|
|
+ ) : (
|
|
|
+ <IdBadge team={team} avatarSize={22} />
|
|
|
+ )
|
|
|
+ }
|
|
|
+ projects={sortProjects(team.projects)}
|
|
|
+ access={new Set(organization.access)}
|
|
|
+ />
|
|
|
+ </LazyLoad>
|
|
|
+ ))}
|
|
|
+ {showResources && <Resources organization={organization} />}
|
|
|
+ </Fragment>
|
|
|
+ );
|
|
|
}
|
|
|
|
|
|
const OrganizationDashboard = (props: Props) => (
|