123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- import {Fragment, JSXElementConstructor, useState} from 'react';
- import styled from '@emotion/styled';
- import flatMap from 'lodash/flatMap';
- import uniqBy from 'lodash/uniqBy';
- import {CommitRowProps} from 'sentry/components/commitRow';
- import {CauseHeader, DataSection} from 'sentry/components/events/styles';
- import Panel from 'sentry/components/panels/panel';
- import {IconAdd, IconSubtract} from 'sentry/icons';
- import {t, tn} from 'sentry/locale';
- import {space} from 'sentry/styles/space';
- import {AvatarProject, Commit, Group} from 'sentry/types';
- import {trackAnalytics} from 'sentry/utils/analytics';
- import {getAnalyticsDataForGroup} from 'sentry/utils/events';
- import useRouteAnalyticsParams from 'sentry/utils/routeAnalytics/useRouteAnalyticsParams';
- import useCommitters from 'sentry/utils/useCommitters';
- import useOrganization from 'sentry/utils/useOrganization';
- interface Props {
- commitRow: JSXElementConstructor<CommitRowProps>;
- eventId: string;
- project: AvatarProject;
- group?: Group;
- }
- export function EventCause({group, eventId, project, commitRow: CommitRow}: Props) {
- const organization = useOrganization();
- const [isExpanded, setIsExpanded] = useState(false);
- const {data, isLoading} = useCommitters({
- eventId,
- projectSlug: project.slug,
- });
- const committers = data?.committers ?? [];
- useRouteAnalyticsParams({
- fetching: isLoading,
- num_suspect_commits: committers.length,
- });
- function getUniqueCommitsWithAuthors() {
- // Get a list of commits with author information attached
- const commitsWithAuthors = flatMap(committers, ({commits, author}) =>
- commits.map(commit => ({
- ...commit,
- author,
- }))
- );
- // Remove duplicate commits
- return uniqBy(commitsWithAuthors, commit => commit.id);
- }
- if (!committers.length) {
- return null;
- }
- const handlePullRequestClick = () => {
- trackAnalytics('issue_details.suspect_commits.pull_request_clicked', {
- organization,
- project_id: parseInt(project.id as string, 10),
- ...getAnalyticsDataForGroup(group),
- });
- };
- const handleCommitClick = (commit: Commit) => {
- trackAnalytics('issue_details.suspect_commits.commit_clicked', {
- organization,
- project_id: parseInt(project.id as string, 10),
- has_pull_request: commit.pullRequest?.id !== undefined,
- ...getAnalyticsDataForGroup(group),
- });
- };
- const commits = getUniqueCommitsWithAuthors();
- const commitHeading = tn('Suspect Commit', 'Suspect Commits (%s)', commits.length);
- return (
- <DataSection>
- <CauseHeader>
- <h3 data-test-id="event-cause">{commitHeading}</h3>
- {commits.length > 1 && (
- <ExpandButton
- onClick={() => setIsExpanded(!isExpanded)}
- data-test-id="expand-commit-list"
- >
- {isExpanded ? (
- <Fragment>
- {t('Show less')} <IconSubtract isCircled size="md" />
- </Fragment>
- ) : (
- <Fragment>
- {t('Show more')} <IconAdd isCircled size="md" />
- </Fragment>
- )}
- </ExpandButton>
- )}
- </CauseHeader>
- <StyledPanel>
- {commits.slice(0, isExpanded ? 100 : 1).map(commit => (
- <CommitRow
- key={commit.id}
- commit={commit}
- onCommitClick={handleCommitClick}
- onPullRequestClick={handlePullRequestClick}
- />
- ))}
- </StyledPanel>
- </DataSection>
- );
- }
- export const StyledPanel = styled(Panel)`
- margin: 0;
- `;
- const ExpandButton = styled('button')`
- display: flex;
- align-items: center;
- gap: ${space(0.5)};
- `;
|