Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(issue-details): Add streamlined sidebar and activity #77958

Merged
merged 12 commits into from
Sep 24, 2024
4 changes: 2 additions & 2 deletions static/app/components/layouts/thirds.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ export const HeaderNavTabs = styled(NavTabs)`
/**
* Base container for 66/33 containers.
*/
export const Body = styled('div')<{noRowGap?: boolean}>`
export const Body = styled('div')<{noRowGap?: boolean; sidebarOpen?: boolean}>`
padding: ${space(2)};
margin: 0;
background-color: ${p => p.theme.background};
Expand All @@ -132,7 +132,7 @@ export const Body = styled('div')<{noRowGap?: boolean}>`
}

@media (min-width: ${p => p.theme.breakpoints.large}) {
display: grid;
display: ${p => (p.sidebarOpen ? 'grid' : 'block')};
grid-template-columns: minmax(100px, auto) 325px;
align-content: start;
gap: ${p => (!p.noRowGap ? `${space(3)}` : `0 ${space(3)}`)};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,11 @@ import {getConfigForIssueType} from 'sentry/utils/issueTypeConfig';
import {VisuallyCompleteWithData} from 'sentry/utils/performanceForSentry';
import normalizeUrl from 'sentry/utils/url/normalizeUrl';
import usePrevious from 'sentry/utils/usePrevious';
import {useSyncedLocalStorageState} from 'sentry/utils/useSyncedLocalStorageState';
import GroupEventDetailsContent from 'sentry/views/issueDetails/groupEventDetails/groupEventDetailsContent';
import GroupEventHeader from 'sentry/views/issueDetails/groupEventHeader';
import GroupSidebar from 'sentry/views/issueDetails/groupSidebar';
import StreamlinedSidebar from 'sentry/views/issueDetails/streamline/sidebar';

import ReprocessingProgress from '../reprocessingProgress';
import {
Expand Down Expand Up @@ -72,6 +74,11 @@ function GroupEventDetails(props: GroupEventDetailsProps) {
const prevEvent = usePrevious(event);
const hasStreamlinedUI = useHasStreamlinedUI();

const [sidebarOpen, _] = useSyncedLocalStorageState(
'issue-details-sidebar-open',
false
);

// load the data
useSentryAppComponentsData({projectId});

Expand Down Expand Up @@ -172,6 +179,7 @@ function GroupEventDetails(props: GroupEventDetailsProps) {
<StyledLayoutBody
data-test-id="group-event-details"
hasStreamlinedUi={hasStreamlinedUI}
sidebarOpen={sidebarOpen}
>
{groupReprocessingStatus === ReprocessingStatus.REPROCESSING ? (
<ReprocessingProgress
Expand All @@ -197,15 +205,23 @@ function GroupEventDetails(props: GroupEventDetailsProps) {
)}
{renderContent()}
</MainLayoutComponent>
<StyledLayoutSide hasStreamlinedUi={hasStreamlinedUI}>
<GroupSidebar
organization={organization}
project={project}
group={group}
event={eventWithMeta}
environments={environments}
/>
</StyledLayoutSide>
{hasStreamlinedUI ? (
sidebarOpen ? (
<StyledLayoutSide hasStreamlinedUi={hasStreamlinedUI}>
<StreamlinedSidebar group={group} event={event} project={project} />
</StyledLayoutSide>
) : null
) : (
<StyledLayoutSide hasStreamlinedUi={hasStreamlinedUI}>
<GroupSidebar
organization={organization}
project={project}
group={group}
event={eventWithMeta}
environments={environments}
/>
</StyledLayoutSide>
)}
</Fragment>
)}
</StyledLayoutBody>
Expand All @@ -214,7 +230,10 @@ function GroupEventDetails(props: GroupEventDetailsProps) {
);
}

const StyledLayoutBody = styled(Layout.Body)<{hasStreamlinedUi: boolean}>`
const StyledLayoutBody = styled(Layout.Body)<{
hasStreamlinedUi: boolean;
sidebarOpen: boolean;
}>`
/* Makes the borders align correctly */
padding: 0 !important;
@media (min-width: ${p => p.theme.breakpoints.large}) {
Expand Down
50 changes: 50 additions & 0 deletions static/app/views/issueDetails/streamline/activitySection.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import {Fragment} from 'react';
import styled from '@emotion/styled';

import Timeline from 'sentry/components/timeline';
import TimeSince from 'sentry/components/timeSince';
import type {Group} from 'sentry/types/group';
import useOrganization from 'sentry/utils/useOrganization';
import {groupActivityTypeIconMapping} from 'sentry/views/issueDetails/streamline/groupActivityIcons';
import getGroupActivityItem from 'sentry/views/issueDetails/streamline/groupActivityItem';

function StreamlinedActivitySection({group}: {group: Group}) {
const organization = useOrganization();

return (
<Fragment>
<Timeline.Container>
{group.activity.map(item => {
const authorName = item.user ? item.user.name : 'Sentry';
const {title, message} = getGroupActivityItem(
item,
organization,
group.project.id,
<Author>{authorName}</Author>
);

const Icon = groupActivityTypeIconMapping[item.type]?.Component ?? null;

return (
<Timeline.Item
title={title}
timestamp={<TimeSince date={item.dateCreated} />}
icon={
Icon && <Icon {...groupActivityTypeIconMapping[item.type].defaultProps} />
}
key={item.id}
>
{message}
</Timeline.Item>
);
})}
</Timeline.Container>
</Fragment>
);
}

const Author = styled('span')`
font-weight: ${p => p.theme.fontWeightBold};
`;

export default StreamlinedActivitySection;
67 changes: 67 additions & 0 deletions static/app/views/issueDetails/streamline/groupActivityIcons.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import {
IconAdd,
IconCheckmark,
IconClose,
IconDelete,
IconEdit,
IconFile,
IconFire,
IconFlag,
IconGraph,
IconLock,
IconMute,
IconNext,
IconPlay,
IconPrevious,
IconRefresh,
IconUnsubscribed,
IconUser,
} from 'sentry/icons';
import {GroupActivityType} from 'sentry/types/group';

interface IconWithDefaultProps {
Component: React.ComponentType<any> | null;
defaultProps: {locked?: boolean; type?: string};
}

export const groupActivityTypeIconMapping: Record<
GroupActivityType,
IconWithDefaultProps
> = {
[GroupActivityType.NOTE]: {Component: IconFile, defaultProps: {}},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you don't need the defaultProps you don't need to add it lol

[GroupActivityType.SET_RESOLVED]: {Component: IconCheckmark, defaultProps: {}},
[GroupActivityType.SET_RESOLVED_BY_AGE]: {Component: IconCheckmark, defaultProps: {}},
[GroupActivityType.SET_RESOLVED_IN_RELEASE]: {
Component: IconCheckmark,
defaultProps: {},
},
[GroupActivityType.SET_RESOLVED_IN_COMMIT]: {
Component: IconCheckmark,
defaultProps: {},
},
[GroupActivityType.SET_RESOLVED_IN_PULL_REQUEST]: {
Component: IconCheckmark,
defaultProps: {},
},
[GroupActivityType.SET_UNRESOLVED]: {Component: IconClose, defaultProps: {}},
[GroupActivityType.SET_IGNORED]: {Component: IconMute, defaultProps: {}},
[GroupActivityType.SET_PUBLIC]: {Component: IconLock, defaultProps: {}},
[GroupActivityType.SET_PRIVATE]: {Component: IconLock, defaultProps: {locked: true}},
[GroupActivityType.SET_REGRESSION]: {Component: IconFire, defaultProps: {}},
[GroupActivityType.CREATE_ISSUE]: {Component: IconAdd, defaultProps: {}},
[GroupActivityType.UNMERGE_SOURCE]: {Component: IconPrevious, defaultProps: {}},
[GroupActivityType.UNMERGE_DESTINATION]: {Component: IconPrevious, defaultProps: {}},
[GroupActivityType.FIRST_SEEN]: {Component: IconFlag, defaultProps: {}},
[GroupActivityType.ASSIGNED]: {Component: IconUser, defaultProps: {}},
[GroupActivityType.UNASSIGNED]: {Component: IconUnsubscribed, defaultProps: {}},
[GroupActivityType.MERGE]: {Component: IconNext, defaultProps: {}},
[GroupActivityType.REPROCESS]: {Component: IconRefresh, defaultProps: {}},
[GroupActivityType.MARK_REVIEWED]: {Component: IconCheckmark, defaultProps: {}},
[GroupActivityType.AUTO_SET_ONGOING]: {Component: IconPlay, defaultProps: {}},
[GroupActivityType.SET_ESCALATING]: {
Component: IconGraph,
defaultProps: {type: 'area'},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh you did

},
[GroupActivityType.SET_PRIORITY]: {Component: IconEdit, defaultProps: {}},
[GroupActivityType.DELETED_ATTACHMENT]: {Component: IconDelete, defaultProps: {}},
};
Loading
Loading