import React from 'react'; import styled from '@emotion/styled'; import {Location} from 'history'; import GuideAnchor from 'app/components/assistant/guideAnchor'; import Button from 'app/components/button'; import Collapsible from 'app/components/collapsible'; import Count from 'app/components/count'; import GlobalSelectionLink from 'app/components/globalSelectionLink'; import ProjectBadge from 'app/components/idBadge/projectBadge'; import NotAvailable from 'app/components/notAvailable'; import {PanelItem} from 'app/components/panels'; import Placeholder from 'app/components/placeholder'; import Tooltip from 'app/components/tooltip'; import {t, tct} from 'app/locale'; import overflowEllipsis from 'app/styles/overflowEllipsis'; import space from 'app/styles/space'; import {Organization, Release, ReleaseProject} from 'app/types'; import {defined} from 'app/utils'; import {getReleaseNewIssuesUrl, getReleaseUnhandledIssuesUrl} from '../../utils'; import {ReleaseHealthRequestRenderProps} from '../../utils/releaseHealthRequest'; import CrashFree from '../crashFree'; import HealthStatsChart from '../healthStatsChart'; import HealthStatsPeriod from '../healthStatsPeriod'; import ReleaseAdoption from '../releaseAdoption'; import {DisplayOption} from '../utils'; import Header from './header'; import ProjectLink from './projectLink'; type Props = { projects: Array; releaseVersion: Release['version']; organization: Organization; activeDisplay: DisplayOption; location: Location; showPlaceholders: boolean; isTopRelease: boolean; getHealthData: ReleaseHealthRequestRenderProps['getHealthData']; }; const Content = ({ projects, releaseVersion, location, organization, activeDisplay, showPlaceholders, isTopRelease, getHealthData, }: Props) => { return (
{t('Project Name')} = 800)} > {t('Adoption')} {t('Crash Free Rate')} {t('Count')} {t('Crashes')} {t('New Issues')}
( )} collapseButton={({onCollapse}) => ( )} > {projects.map((project, index) => { const {id, slug, newGroups} = project; const crashCount = getHealthData.getCrashCount( releaseVersion, id, DisplayOption.SESSIONS ); const crashFreeRate = getHealthData.getCrashFreeRate( releaseVersion, id, activeDisplay ); const get24hCountByRelease = getHealthData.get24hCountByRelease( releaseVersion, id, activeDisplay ); const get24hCountByProject = getHealthData.get24hCountByProject( id, activeDisplay ); const timeSeries = getHealthData.getTimeSeries( releaseVersion, id, activeDisplay ); const adoption = getHealthData.getAdoption(releaseVersion, id, activeDisplay); // we currently don't support sub-hour session intervals, we rather hide the count histogram than to show only two bars const hasCountHistogram = timeSeries?.[0].data.length > 7 && timeSeries[0].data.some(item => item.value > 0); return ( {showPlaceholders ? ( ) : get24hCountByProject ? ( ) : ( )} {showPlaceholders ? ( ) : defined(crashFreeRate) ? ( ) : ( )} {showPlaceholders ? ( ) : hasCountHistogram ? ( ) : ( )} {showPlaceholders ? ( ) : defined(crashCount) ? ( ) : ( )} ); })}
); }; export default Content; const ProjectRows = styled('div')` position: relative; `; const ExpandButtonWrapper = styled('div')` position: absolute; width: 100%; bottom: 0; display: flex; align-items: center; justify-content: center; background-image: linear-gradient( 180deg, hsla(0, 0%, 100%, 0.15) 0, ${p => p.theme.white} ); background-repeat: repeat-x; border-bottom: ${space(1)} solid ${p => p.theme.white}; border-top: ${space(1)} solid transparent; border-bottom-right-radius: ${p => p.theme.borderRadius}; @media (max-width: ${p => p.theme.breakpoints[1]}) { border-bottom-left-radius: ${p => p.theme.borderRadius}; } `; const CollapseButtonWrapper = styled('div')` display: flex; align-items: center; justify-content: center; height: 41px; `; const ProjectRow = styled(PanelItem)` padding: ${space(1)} ${space(2)}; @media (min-width: ${p => p.theme.breakpoints[1]}) { font-size: ${p => p.theme.fontSizeMedium}; } `; const Layout = styled('div')` display: grid; grid-template-columns: 1fr 1.4fr 0.6fr 0.7fr; grid-column-gap: ${space(1)}; align-items: center; width: 100%; @media (min-width: ${p => p.theme.breakpoints[0]}) { grid-template-columns: 1fr 1fr 1fr 0.5fr 0.5fr 0.5fr; } @media (min-width: ${p => p.theme.breakpoints[1]}) { grid-template-columns: 1fr 0.8fr 1fr 0.5fr 0.5fr 0.6fr; } @media (min-width: ${p => p.theme.breakpoints[3]}) { grid-template-columns: 1fr 0.8fr 1fr 1fr 0.5fr 0.5fr 0.5fr; } `; const Column = styled('div')` ${overflowEllipsis}; line-height: 20px; `; const NewIssuesColumn = styled(Column)` @media (min-width: ${p => p.theme.breakpoints[0]}) { text-align: right; } `; const AdoptionColumn = styled(Column)` display: none; @media (min-width: ${p => p.theme.breakpoints[0]}) { display: flex; /* Chart tooltips need overflow */ overflow: visible; } `; const AdoptionWrapper = styled('span')` display: inline-grid; grid-template-columns: 70px 1fr; grid-gap: ${space(1)}; align-items: center; @media (min-width: ${p => p.theme.breakpoints[3]}) { grid-template-columns: 90px 1fr; } `; const CrashFreeRateColumn = styled(Column)` @media (min-width: ${p => p.theme.breakpoints[0]}) { text-align: center; } `; const CountColumn = styled(Column)` display: none; @media (min-width: ${p => p.theme.breakpoints[3]}) { display: flex; /* Chart tooltips need overflow */ overflow: visible; } `; const CrashesColumn = styled(Column)` display: none; @media (min-width: ${p => p.theme.breakpoints[0]}) { display: block; text-align: right; } `; const ViewColumn = styled(Column)` text-align: right; `; const ChartWrapper = styled('div')` flex: 1; g > .barchart-rect { background: ${p => p.theme.gray200}; fill: ${p => p.theme.gray200}; } `; const StyledPlaceholder = styled(Placeholder)` height: 15px; display: inline-block; position: relative; top: ${space(0.25)}; `;