import {Fragment} from 'react';
import styled from '@emotion/styled';
import {motion, Variants} from 'framer-motion';
import {PlatformIcon} from 'platformicons';
import {PlatformKey} from 'sentry/data/platformCategories';
import platforms from 'sentry/data/platforms';
import {IconCheckmark} from 'sentry/icons';
import {t} from 'sentry/locale';
import pulsingIndicatorStyles from 'sentry/styles/pulsingIndicator';
import space from 'sentry/styles/space';
import {Project} from 'sentry/types';
import testableTransition from 'sentry/utils/testableTransition';
type Props = {
activeProject: Project | null;
checkProjectHasFirstEvent: (project: Project) => boolean;
projects: Project[];
selectProject: (newProjectId: string) => void;
// A map from selected platform keys to the projects created by onboarding.
selectedPlatformToProjectIdMap: {[key in PlatformKey]?: string};
};
function ProjectSidebarSection({
projects,
activeProject,
selectProject,
checkProjectHasFirstEvent,
selectedPlatformToProjectIdMap,
}: Props) {
const oneProject = (platformOnCreate: string, projectSlug: string) => {
const project = projects.find(p => p.slug === projectSlug);
const platform = project ? project.platform || 'other' : platformOnCreate;
const platformName = platforms.find(p => p.id === platform)?.name ?? '';
const isActive = !!project && activeProject?.id === project.id;
const errorReceived = !!project && checkProjectHasFirstEvent(project);
return (
project && selectProject(project.id)}
disabled={!project}
>
{platformName}
{!project
? t('Project Deleted')
: errorReceived
? t('Error Received')
: t('Waiting for error')}
{errorReceived ? (
) : (
isActive &&
)}
);
};
return (
{t('Projects to Setup')}
{Object.entries(selectedPlatformToProjectIdMap).map(
([platformOnCreate, projectSlug]) => oneProject(platformOnCreate, projectSlug)
)}
);
}
export default ProjectSidebarSection;
const Title = styled('span')`
font-size: 12px;
font-weight: 600;
text-transform: uppercase;
margin-left: ${space(2)};
`;
const SubHeader = styled('div')<{errorReceived: boolean}>`
color: ${p => (p.errorReceived ? p.theme.successText : p.theme.pink300)};
`;
const StyledPlatformIcon = styled(PlatformIcon)``;
const ProjectWrapper = styled('div')<{disabled: boolean; isActive: boolean}>`
display: flex;
flex-direction: row;
align-items: center;
background-color: ${p => p.isActive && p.theme.gray100};
padding: ${space(2)};
cursor: pointer;
border-radius: 4px;
user-select: none;
${p =>
p.disabled &&
`
cursor: not-allowed;
${StyledPlatformIcon} {
filter: grayscale(1);
}
${SubHeader} {
color: ${p.theme.gray400};
}
${NameWrapper} {
text-decoration-line: line-through;
}
`}
`;
const indicatorAnimation: Variants = {
initial: {opacity: 0, y: -10},
animate: {opacity: 1, y: 0},
exit: {opacity: 0, y: 10},
};
const WaitingIndicator = styled(motion.div)`
margin: 0 6px;
flex-shrink: 0;
${pulsingIndicatorStyles};
background-color: ${p => p.theme.pink300};
`;
const StyledIconCheckmark = styled(IconCheckmark)`
flex-shrink: 0;
`;
WaitingIndicator.defaultProps = {
variants: indicatorAnimation,
transition: testableTransition(),
};
const MiddleWrapper = styled('div')`
margin: 0 ${space(1)};
flex-grow: 1;
overflow: hidden;
`;
const NameWrapper = styled('div')`
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
`;