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): Display the resolution/archival reason on new UI #83555

Merged
merged 3 commits into from
Jan 16, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
127 changes: 65 additions & 62 deletions static/app/components/archivedBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,76 +12,79 @@ interface ArchivedBoxProps {
organization: Organization;
statusDetails: IgnoredStatusDetails;
substatus: Group['substatus'];
hasStreamlinedUI?: boolean;
}

function ArchivedBox({substatus, statusDetails, organization}: ArchivedBoxProps) {
function trackDocsClick() {
trackAnalytics('issue_details.issue_status_docs_clicked', {
organization,
});
}

function renderReason() {
const {ignoreUntil, ignoreCount, ignoreWindow, ignoreUserCount, ignoreUserWindow} =
statusDetails;
export function renderArchiveReason({
substatus,
statusDetails,
organization,
hasStreamlinedUI = false,
}: ArchivedBoxProps) {
const {ignoreUntil, ignoreCount, ignoreWindow, ignoreUserCount, ignoreUserWindow} =
statusDetails;

if (substatus === GroupSubstatus.ARCHIVED_UNTIL_ESCALATING) {
return t(
"This issue has been archived. It'll return to your inbox if it escalates. To learn more, %s",
<ExternalLink
href="https://docs.sentry.io/product/issues/states-triage/#archive"
onClick={trackDocsClick}
>
{t('read the docs')}
</ExternalLink>
);
}
if (ignoreUntil) {
return t(
'This issue has been archived until %s.',
<strong>
<DateTime date={ignoreUntil} />
</strong>
);
}
if (ignoreCount && ignoreWindow) {
return t(
'This issue has been archived until it occurs %s time(s) in %s.',
<strong>{ignoreCount.toLocaleString()}</strong>,
<strong>
<Duration seconds={ignoreWindow * 60} />
</strong>
);
}
if (ignoreCount) {
return t(
'This issue has been archived until it occurs %s more time(s).',
<strong>{ignoreCount.toLocaleString()}</strong>
);
}
if (ignoreUserCount && ignoreUserWindow) {
return t(
'This issue has been archived until it affects %s user(s) in %s.',
<strong>{ignoreUserCount.toLocaleString()}</strong>,
<strong>
<Duration seconds={ignoreUserWindow * 60} />
</strong>
);
}
if (ignoreUserCount) {
return t(
'This issue has been archived until it affects %s more user(s).',
<strong>{ignoreUserCount.toLocaleString()}</strong>
);
}

return t('This issue has been archived forever.');
if (substatus === GroupSubstatus.ARCHIVED_UNTIL_ESCALATING) {
return hasStreamlinedUI
? t('This issue has been archived until it escalates.')
: t(
"This issue has been archived. It'll return to your inbox if it escalates. To learn more, %s",
<ExternalLink
href="https://docs.sentry.io/product/issues/states-triage/#archive"
onClick={() =>
trackAnalytics('issue_details.issue_status_docs_clicked', {organization})
}
>
{t('read the docs')}
</ExternalLink>
);
}
if (ignoreUntil) {
return t(
'This issue has been archived until %s.',
<strong>
<DateTime date={ignoreUntil} />
</strong>
);
}
if (ignoreCount && ignoreWindow) {
return t(
'This issue has been archived until it occurs %s time(s) in %s.',
<strong>{ignoreCount.toLocaleString()}</strong>,
<strong>
<Duration seconds={ignoreWindow * 60} />
</strong>
);
}
if (ignoreCount) {
return t(
'This issue has been archived until it occurs %s more time(s).',
<strong>{ignoreCount.toLocaleString()}</strong>
);
}
if (ignoreUserCount && ignoreUserWindow) {
return t(
'This issue has been archived until it affects %s user(s) in %s.',
<strong>{ignoreUserCount.toLocaleString()}</strong>,
<strong>
<Duration seconds={ignoreUserWindow * 60} />
</strong>
);
}
if (ignoreUserCount) {
return t(
'This issue has been archived until it affects %s more user(s).',
<strong>{ignoreUserCount.toLocaleString()}</strong>
);
}

return t('This issue has been archived forever.');
}
function ArchivedBox({substatus, statusDetails, organization}: ArchivedBoxProps) {
return (
<BannerContainer priority="default">
<BannerSummary>
<span>{renderReason()}</span>
<span>{renderArchiveReason({substatus, statusDetails, organization})}</span>
</BannerSummary>
</BannerContainer>
);
Expand Down
23 changes: 14 additions & 9 deletions static/app/components/resolutionBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,20 @@ type Props = {
activities?: GroupActivity[];
};

function renderReason(
statusDetails: ResolvedStatusDetails,
projectId: string,
activities: GroupActivity[]
) {
export function renderResolutionReason({
statusDetails,
projectId,
activities = [],
hasStreamlinedUI = false,
}: Props & {hasStreamlinedUI?: boolean}) {
const actor = statusDetails.actor ? (
<strong>
<UserAvatar user={statusDetails.actor} size={20} className="avatar" />
<span style={{marginLeft: 5}}>{statusDetails.actor.name}</span>
{!hasStreamlinedUI && (
<UserAvatar user={statusDetails.actor} size={20} className="avatar" />
)}
<span style={{marginLeft: hasStreamlinedUI ? 0 : 5}}>
{statusDetails.actor.name}
</span>
</strong>
) : null;

Expand Down Expand Up @@ -115,15 +120,15 @@ function renderReason(
),
});
}
return t('This issue has been marked as resolved.');
return hasStreamlinedUI ? null : t('This issue has been marked as resolved.');
}

function ResolutionBox({statusDetails, projectId, activities = []}: Props) {
return (
<BannerContainer priority="default">
<BannerSummary>
<StyledIconCheckmark color="successText" />
<span>{renderReason(statusDetails, projectId, activities)}</span>
<span>{renderResolutionReason({statusDetails, projectId, activities})}</span>
</BannerSummary>
</BannerContainer>
);
Expand Down
36 changes: 33 additions & 3 deletions static/app/views/issueDetails/actions/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@ import Feature from 'sentry/components/acl/feature';
import FeatureDisabled from 'sentry/components/acl/featureDisabled';
import ArchiveActions, {getArchiveActions} from 'sentry/components/actions/archive';
import ResolveActions from 'sentry/components/actions/resolve';
import {renderArchiveReason} from 'sentry/components/archivedBox';
import GuideAnchor from 'sentry/components/assistant/guideAnchor';
import {Button, LinkButton} from 'sentry/components/button';
import {Flex} from 'sentry/components/container/flex';
import {DropdownMenu} from 'sentry/components/dropdownMenu';
import {EnvironmentPageFilter} from 'sentry/components/organizations/environmentPageFilter';
import {renderResolutionReason} from 'sentry/components/resolutionBox';
import {
IconCheckmark,
IconEllipsis,
Expand Down Expand Up @@ -367,9 +370,30 @@ export function GroupActions({group, project, disabled, event}: GroupActionsProp
(isResolved || isIgnored ? (
<ResolvedActionWapper>
<ResolvedWrapper>
<IconCheckmark />
{isResolved ? resolvedCopyCap || t('Resolved') : t('Archived')}
<IconCheckmark size="md" />
<Flex column>
{isResolved ? resolvedCopyCap || t('Resolved') : t('Archived')}
<ReasonBanner>
{group.status === 'resolved'
? renderResolutionReason({
statusDetails: group.statusDetails,
projectId: project.id,
activities: group.activity,
hasStreamlinedUI,
})
: null}
{group.status === 'ignored'
? renderArchiveReason({
substatus: group.substatus,
statusDetails: group.statusDetails,
organization,
hasStreamlinedUI,
})
: null}
</ReasonBanner>
</Flex>
</ResolvedWrapper>

<Divider />
{resolveCap.enabled && (
<Button
Expand Down Expand Up @@ -608,7 +632,7 @@ const ActionWrapper = styled('div')`

const ResolvedWrapper = styled('div')`
display: flex;
gap: ${space(0.5)};
gap: ${space(1.5)};
align-items: center;
color: ${p => p.theme.green400};
font-weight: bold;
Expand All @@ -620,3 +644,9 @@ const ResolvedActionWapper = styled('div')`
gap: ${space(1)};
align-items: center;
`;

const ReasonBanner = styled('div')`
leeandher marked this conversation as resolved.
Show resolved Hide resolved
font-weight: normal;
color: ${p => p.theme.green400};
font-size: ${p => p.theme.fontSizeSmall};
`;
Loading