|
@@ -1,11 +1,14 @@
|
|
-import React from 'react';
|
|
|
|
|
|
+import {ComponentProps, Fragment} from 'react';
|
|
|
|
+import {Link} from 'react-router';
|
|
import styled from '@emotion/styled';
|
|
import styled from '@emotion/styled';
|
|
|
|
|
|
import Duration from 'sentry/components/duration';
|
|
import Duration from 'sentry/components/duration';
|
|
import ProjectBadge from 'sentry/components/idBadge/projectBadge';
|
|
import ProjectBadge from 'sentry/components/idBadge/projectBadge';
|
|
import Placeholder from 'sentry/components/placeholder';
|
|
import Placeholder from 'sentry/components/placeholder';
|
|
|
|
+import Tag, {Background} from 'sentry/components/tag';
|
|
import TimeSince from 'sentry/components/timeSince';
|
|
import TimeSince from 'sentry/components/timeSince';
|
|
-import {IconCalendar, IconClock, IconFire} from 'sentry/icons';
|
|
|
|
|
|
+import {IconCalendar, IconClock} from 'sentry/icons';
|
|
|
|
+import {t} from 'sentry/locale';
|
|
import space from 'sentry/styles/space';
|
|
import space from 'sentry/styles/space';
|
|
import useProjects from 'sentry/utils/useProjects';
|
|
import useProjects from 'sentry/utils/useProjects';
|
|
import {useRouteContext} from 'sentry/utils/useRouteContext';
|
|
import {useRouteContext} from 'sentry/utils/useRouteContext';
|
|
@@ -17,20 +20,27 @@ type Props = {
|
|
|
|
|
|
function ReplayMetaData({replayRecord}: Props) {
|
|
function ReplayMetaData({replayRecord}: Props) {
|
|
const {
|
|
const {
|
|
|
|
+ location: {pathname, query},
|
|
params: {replaySlug},
|
|
params: {replaySlug},
|
|
} = useRouteContext();
|
|
} = useRouteContext();
|
|
const {projects} = useProjects();
|
|
const {projects} = useProjects();
|
|
const [slug] = replaySlug.split(':');
|
|
const [slug] = replaySlug.split(':');
|
|
|
|
|
|
|
|
+ const errorsTabHref = {
|
|
|
|
+ pathname,
|
|
|
|
+ query: {
|
|
|
|
+ ...query,
|
|
|
|
+ t_main: 'console',
|
|
|
|
+ f_c_logLevel: 'error',
|
|
|
|
+ f_c_search: undefined,
|
|
|
|
+ },
|
|
|
|
+ };
|
|
|
|
+
|
|
return (
|
|
return (
|
|
<KeyMetrics>
|
|
<KeyMetrics>
|
|
{replayRecord ? (
|
|
{replayRecord ? (
|
|
<ProjectBadge
|
|
<ProjectBadge
|
|
- project={
|
|
|
|
- projects.find(p => p.id === replayRecord.projectId) || {
|
|
|
|
- slug,
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+ project={projects.find(p => p.id === replayRecord.projectId) || {slug}}
|
|
avatarSize={16}
|
|
avatarSize={16}
|
|
/>
|
|
/>
|
|
) : (
|
|
) : (
|
|
@@ -39,30 +49,32 @@ function ReplayMetaData({replayRecord}: Props) {
|
|
|
|
|
|
<KeyMetricData>
|
|
<KeyMetricData>
|
|
{replayRecord ? (
|
|
{replayRecord ? (
|
|
- <React.Fragment>
|
|
|
|
|
|
+ <Fragment>
|
|
<IconCalendar color="gray300" />
|
|
<IconCalendar color="gray300" />
|
|
<TimeSince date={replayRecord.startedAt} shorten />
|
|
<TimeSince date={replayRecord.startedAt} shorten />
|
|
- </React.Fragment>
|
|
|
|
|
|
+ </Fragment>
|
|
) : (
|
|
) : (
|
|
<HeaderPlaceholder />
|
|
<HeaderPlaceholder />
|
|
)}
|
|
)}
|
|
</KeyMetricData>
|
|
</KeyMetricData>
|
|
<KeyMetricData>
|
|
<KeyMetricData>
|
|
{replayRecord ? (
|
|
{replayRecord ? (
|
|
- <React.Fragment>
|
|
|
|
|
|
+ <Fragment>
|
|
<IconClock color="gray300" />
|
|
<IconClock color="gray300" />
|
|
<Duration seconds={replayRecord?.duration} abbreviation exact />
|
|
<Duration seconds={replayRecord?.duration} abbreviation exact />
|
|
- </React.Fragment>
|
|
|
|
|
|
+ </Fragment>
|
|
) : (
|
|
) : (
|
|
<HeaderPlaceholder />
|
|
<HeaderPlaceholder />
|
|
)}
|
|
)}
|
|
</KeyMetricData>
|
|
</KeyMetricData>
|
|
<KeyMetricData>
|
|
<KeyMetricData>
|
|
{replayRecord ? (
|
|
{replayRecord ? (
|
|
- <React.Fragment>
|
|
|
|
- <IconFire color="red300" />
|
|
|
|
- {replayRecord?.countErrors}
|
|
|
|
- </React.Fragment>
|
|
|
|
|
|
+ <Fragment>
|
|
|
|
+ <ErrorTag to={errorsTabHref} icon={null} type="error">
|
|
|
|
+ {replayRecord?.countErrors}
|
|
|
|
+ </ErrorTag>
|
|
|
|
+ <Link to={errorsTabHref}>{t('Errors')}</Link>
|
|
|
|
+ </Fragment>
|
|
) : (
|
|
) : (
|
|
<HeaderPlaceholder />
|
|
<HeaderPlaceholder />
|
|
)}
|
|
)}
|
|
@@ -71,11 +83,9 @@ function ReplayMetaData({replayRecord}: Props) {
|
|
);
|
|
);
|
|
}
|
|
}
|
|
|
|
|
|
-export const HeaderPlaceholder = styled(function HeaderPlaceholder(
|
|
|
|
- props: React.ComponentProps<typeof Placeholder>
|
|
|
|
-) {
|
|
|
|
- return <Placeholder width="80px" height="19px" {...props} />;
|
|
|
|
-})`
|
|
|
|
|
|
+export const HeaderPlaceholder = styled((props: ComponentProps<typeof Placeholder>) => (
|
|
|
|
+ <Placeholder width="80px" height="19px" {...props} />
|
|
|
|
+))`
|
|
background-color: ${p => p.theme.background};
|
|
background-color: ${p => p.theme.background};
|
|
`;
|
|
`;
|
|
|
|
|
|
@@ -98,4 +108,15 @@ const KeyMetricData = styled('div')`
|
|
line-height: ${p => p.theme.text.lineHeightBody};
|
|
line-height: ${p => p.theme.text.lineHeightBody};
|
|
`;
|
|
`;
|
|
|
|
|
|
|
|
+const ErrorTag = styled(Tag)`
|
|
|
|
+ ${Background} {
|
|
|
|
+ background: ${p => p.theme.tag.error.iconColor};
|
|
|
|
+ padding: 0 ${space(0.75)};
|
|
|
|
+
|
|
|
|
+ span {
|
|
|
|
+ color: white !important;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+`;
|
|
|
|
+
|
|
export default ReplayMetaData;
|
|
export default ReplayMetaData;
|