Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 50 additions & 67 deletions static/app/views/organizationGroupDetails/grouping/grouping.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {Fragment, useEffect, useState} from 'react';
import {useEffect, useState} from 'react';
import styled from '@emotion/styled';
import {Location} from 'history';
import debounce from 'lodash/debounce';

import {Client} from 'app/api';
import Button from 'app/components/button';
Expand All @@ -10,6 +11,7 @@ import ListItem from 'app/components/list/listItem';
import LoadingError from 'app/components/loadingError';
import LoadingIndicator from 'app/components/loadingIndicator';
import Pagination from 'app/components/pagination';
import {DEFAULT_DEBOUNCE_DURATION} from 'app/constants';
import {IconFlag} from 'app/icons';
import {t, tct} from 'app/locale';
import space from 'app/styles/space';
Expand All @@ -30,10 +32,16 @@ type Props = {
api: Client;
};

type ErrorCode = 'not_hierarchical' | 'no_events' | 'merged_issues' | 'missing_feature';

type Error = {
status: number;
responseJSON?: {
detail: string;
detail: {
code: ErrorCode;
extra: Record<string, any>;
message: string;
};
};
};

Expand Down Expand Up @@ -76,6 +84,10 @@ function Grouping({api, groupId, location}: Props) {
fetchGroupingLevelDetails();
}, [activeGroupingLevel, location.query]);

const handleSetActiveGroupingLevel = debounce((groupingLevelId: string) => {
setActiveGroupingLevel(Number(groupingLevelId));
}, DEFAULT_DEBOUNCE_DURATION);

async function fetchGroupingLevels() {
setIsLoading(true);
setError(undefined);
Expand Down Expand Up @@ -135,19 +147,23 @@ function Grouping({api, groupId, location}: Props) {

if (error) {
if (error.status === 403 && error.responseJSON?.detail) {
const {message, code} = error.responseJSON.detail;
return (
<Wrapper>
<EmptyMessage
size="large"
icon={<IconFlag size="xl" />}
action={
<Button
to={`/organizations/sentry/issues/${groupId}/merged/?${location.search}`}
>
{t('Unmerge issue')}
</Button>
code === 'merged_issues' ? (
<Button
to={`/organizations/sentry/issues/${groupId}/merged/?${location.search}`}
>
{t('Unmerge issue')}
</Button>
) : undefined
}
>
{error.responseJSON.detail}
{message}
</EmptyMessage>
</Wrapper>
);
Expand All @@ -169,10 +185,6 @@ function Grouping({api, groupId, location}: Props) {
);
}

//function handleRegroup() {
// Todo(Priscila): Implement it
//}

const links = parseLinkHeader(pagination);
const hasMore = links.previous?.results || links.next?.results;

Expand All @@ -196,59 +208,37 @@ function Grouping({api, groupId, location}: Props) {
return value === 0 ? t('Automatically grouped') : t('Level %s', value);
}}
value={activeGroupingLevel ?? 0}
onChange={groupingLevelId =>
setActiveGroupingLevel(Number(groupingLevelId))
}
onChange={handleSetActiveGroupingLevel}
/>
</StyledListItem>
<StyledListItem>
{isGroupingLevelDetailsLoading ? (
<div>
<div>{t('What happens to this issue')}</div>
<LoadingIndicator mini />
</div>
) : (
<Fragment>
<div>
{t('What happens to this issue')}
<WhatHappensDescription>
{tct(
`This issue will be deleted and [quantity] new issues will be created.`,
{
quantity: hasMore
? `${activeGroupingLevelDetails.length}+`
: activeGroupingLevelDetails.length,
}
)}
</WhatHappensDescription>
</div>
<NewIssues>
{activeGroupingLevelDetails.map(activeGroupingLevelDetail => (
<NewIssue
key={activeGroupingLevelDetail.hash}
sampleEvent={activeGroupingLevelDetail.latestEvent}
eventCount={activeGroupingLevelDetail.eventCount}
/>
))}
</NewIssues>
</Fragment>
)}
<div>
{t('What happens to this issue')}
<WhatHappensDescription>
{tct(
`This issue will be deleted and [quantity] new issues will be created.`,
{
quantity: hasMore
? `${activeGroupingLevelDetails.length}+`
: activeGroupingLevelDetails.length,
}
)}
</WhatHappensDescription>
</div>
<NewIssues>
{activeGroupingLevelDetails.map(({hash, latestEvent, eventCount}) => (
<NewIssue
key={hash}
sampleEvent={latestEvent}
eventCount={eventCount}
isReloading={isGroupingLevelDetailsLoading}
/>
))}
</NewIssues>
</StyledListItem>
</StyledList>
<Pagination pageLinks={pagination} />
</div>
<Action>
<Button
priority="primary"
disabled={
isGroupingLevelDetailsLoading ||
!activeGroupingLevel ||
activeGroupingLevel === 0
}
>
{t('Regroup')}
</Button>
</Action>
</Wrapper>
);
}
Expand All @@ -258,6 +248,7 @@ export default withApi(Grouping);
const Wrapper = styled('div')`
flex: 1;
display: grid;
align-content: flex-start;
background: ${p => p.theme.background};
grid-gap: ${space(2)};
margin: -${space(3)} -${space(4)};
Expand All @@ -268,21 +259,13 @@ const Description = styled('p')`
margin-bottom: ${space(0.5)};
`;

const Action = styled('div')`
border-top: 1px solid ${p => p.theme.border};
display: flex;
justify-content: flex-end;
padding: ${space(2)} 0 0;
margin-top: ${space(1)};
`;

const StyledListItem = styled(ListItem)`
display: grid;
grid-gap: ${space(1.5)};
`;

const StyledRangeSlider = styled(RangeSlider)`
max-width: 20%;
max-width: 300px;
`;

const StyledList = styled(List)`
Expand Down
13 changes: 10 additions & 3 deletions static/app/views/organizationGroupDetails/grouping/newIssue.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@ import {Event} from 'app/types/event';
type Props = {
sampleEvent: Event;
eventCount: number;
isReloading: boolean;
};

function NewIssue({sampleEvent, eventCount}: Props) {
function NewIssue({sampleEvent, eventCount, isReloading}: Props) {
const {title, culprit} = sampleEvent;
return (
<StyledCard interactive={false}>
<StyledCard interactive={false} isReloading={isReloading}>
<div>
<Title>{title}</Title>
<CulPrint>{culprit}</CulPrint>
Expand All @@ -28,7 +29,7 @@ function NewIssue({sampleEvent, eventCount}: Props) {

export default NewIssue;

const StyledCard = styled(Card)`
const StyledCard = styled(Card)<{isReloading: boolean}>`
margin-bottom: -1px;
overflow: hidden;
display: grid;
Expand All @@ -37,6 +38,12 @@ const StyledCard = styled(Card)`
padding: ${space(1.5)} ${space(2)};
grid-gap: ${space(2)};
word-break: break-word;
${p =>
p.isReloading &&
`
opacity: 0.5;
pointer-events: none;
`}
`;

const Title = styled('div')`
Expand Down