From fa429dcc203bdd2422ee6b409a3dc1a984e80250 Mon Sep 17 00:00:00 2001 From: Scott Cooper Date: Thu, 11 Jun 2026 15:23:59 -0700 Subject: [PATCH 1/5] fix(issues): Show auto-resolve activity age --- static/app/types/group.tsx | 4 +++- .../activitySection/groupActivityItem.tsx | 15 +++++++++---- .../activitySection/index.spec.tsx | 22 +++++++++++++++++++ 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/static/app/types/group.tsx b/static/app/types/group.tsx index 49ba7cbdc45e67..16f0bb309428df 100644 --- a/static/app/types/group.tsx +++ b/static/app/types/group.tsx @@ -700,7 +700,9 @@ interface GroupActivitySetPrivate extends GroupActivityBase { } interface GroupActivitySetByAge extends GroupActivityBase { - data: Record; + data: { + age?: number; + }; type: GroupActivityType.SET_RESOLVED_BY_AGE; } diff --git a/static/app/views/issueDetails/activitySection/groupActivityItem.tsx b/static/app/views/issueDetails/activitySection/groupActivityItem.tsx index 55d5b96707c4ae..338a07beab2d83 100644 --- a/static/app/views/issueDetails/activitySection/groupActivityItem.tsx +++ b/static/app/views/issueDetails/activitySection/groupActivityItem.tsx @@ -287,13 +287,20 @@ export function getGroupActivityItem( message: resolvedMessage, }; } - case GroupActivityType.SET_RESOLVED_BY_AGE: + case GroupActivityType.SET_RESOLVED_BY_AGE: { + const age = activity.data.age; return { title: t('Resolved'), - message: tct('by [author] due to inactivity', { - author, - }), + message: age + ? tct('by [author] after [duration] of inactivity', { + author, + duration: , + }) + : tct('by [author] due to inactivity', { + author, + }), }; + } case GroupActivityType.SET_RESOLVED_IN_RELEASE: { const hasIntegration = 'integration_id' in activity.data && activity.data.integration_id; diff --git a/static/app/views/issueDetails/activitySection/index.spec.tsx b/static/app/views/issueDetails/activitySection/index.spec.tsx index 1b7036725117d6..327566ccffd70f 100644 --- a/static/app/views/issueDetails/activitySection/index.spec.tsx +++ b/static/app/views/issueDetails/activitySection/index.spec.tsx @@ -346,6 +346,28 @@ describe('ActivitySection', () => { expect(screen.getByText('Linked external issue')).toBeInTheDocument(); }); + it('renders auto-resolved activity age as an inactivity duration', async () => { + const autoResolvedGroup = GroupFixture({ + id: '1347', + activity: [ + { + type: GroupActivityType.SET_RESOLVED_BY_AGE, + id: 'set-resolved-by-age-1', + dateCreated: '2020-01-01T00:00:00', + data: {age: 504}, + user: null, + }, + ], + project, + }); + + render(); + + expect(await screen.findByText('Resolved')).toBeInTheDocument(); + expect(screen.getByText('3 weeks')).toBeInTheDocument(); + expect(screen.getByText(/of inactivity/)).toBeInTheDocument(); + }); + it('renders note and allows for edit', async () => { jest.spyOn(indicators, 'addSuccessMessage'); From 36eb5f570c2c7a3ab68f334371725b41f2ff21e2 Mon Sep 17 00:00:00 2001 From: Scott Cooper Date: Thu, 11 Jun 2026 15:27:04 -0700 Subject: [PATCH 2/5] fix(issues): Show auto-resolve age in days --- .../views/issueDetails/activitySection/groupActivityItem.tsx | 5 +++-- static/app/views/issueDetails/activitySection/index.spec.tsx | 3 +-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/static/app/views/issueDetails/activitySection/groupActivityItem.tsx b/static/app/views/issueDetails/activitySection/groupActivityItem.tsx index 338a07beab2d83..47bb0896ba3d28 100644 --- a/static/app/views/issueDetails/activitySection/groupActivityItem.tsx +++ b/static/app/views/issueDetails/activitySection/groupActivityItem.tsx @@ -289,12 +289,13 @@ export function getGroupActivityItem( } case GroupActivityType.SET_RESOLVED_BY_AGE: { const age = activity.data.age; + const ageInDays = age ? Math.round(age / 24) : null; return { title: t('Resolved'), - message: age + message: ageInDays ? tct('by [author] after [duration] of inactivity', { author, - duration: , + duration: tn('%s day', '%s days', ageInDays), }) : tct('by [author] due to inactivity', { author, diff --git a/static/app/views/issueDetails/activitySection/index.spec.tsx b/static/app/views/issueDetails/activitySection/index.spec.tsx index 327566ccffd70f..774afaf157a7c8 100644 --- a/static/app/views/issueDetails/activitySection/index.spec.tsx +++ b/static/app/views/issueDetails/activitySection/index.spec.tsx @@ -364,8 +364,7 @@ describe('ActivitySection', () => { render(); expect(await screen.findByText('Resolved')).toBeInTheDocument(); - expect(screen.getByText('3 weeks')).toBeInTheDocument(); - expect(screen.getByText(/of inactivity/)).toBeInTheDocument(); + expect(screen.getByText(/after 21 days of inactivity/)).toBeInTheDocument(); }); it('renders note and allows for edit', async () => { From 13a2612d1872dd99c60b05827402d1a4c8a10e8b Mon Sep 17 00:00:00 2001 From: Scott Cooper Date: Thu, 11 Jun 2026 15:34:08 -0700 Subject: [PATCH 3/5] fix(issues): Handle sub-day auto-resolve activity age --- .../activitySection/groupActivityItem.tsx | 11 ++++++++--- .../views/issueDetails/activitySection/index.spec.tsx | 11 +++++++++-- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/static/app/views/issueDetails/activitySection/groupActivityItem.tsx b/static/app/views/issueDetails/activitySection/groupActivityItem.tsx index 47bb0896ba3d28..c0e3280115e342 100644 --- a/static/app/views/issueDetails/activitySection/groupActivityItem.tsx +++ b/static/app/views/issueDetails/activitySection/groupActivityItem.tsx @@ -289,13 +289,18 @@ export function getGroupActivityItem( } case GroupActivityType.SET_RESOLVED_BY_AGE: { const age = activity.data.age; - const ageInDays = age ? Math.round(age / 24) : null; + const duration = + age && age >= 24 + ? tn('%s day', '%s days', Math.round(age / 24)) + : age + ? tn('%s hour', '%s hours', age) + : null; return { title: t('Resolved'), - message: ageInDays + message: duration ? tct('by [author] after [duration] of inactivity', { author, - duration: tn('%s day', '%s days', ageInDays), + duration, }) : tct('by [author] due to inactivity', { author, diff --git a/static/app/views/issueDetails/activitySection/index.spec.tsx b/static/app/views/issueDetails/activitySection/index.spec.tsx index 774afaf157a7c8..ea68aa81aa5633 100644 --- a/static/app/views/issueDetails/activitySection/index.spec.tsx +++ b/static/app/views/issueDetails/activitySection/index.spec.tsx @@ -357,14 +357,21 @@ describe('ActivitySection', () => { data: {age: 504}, user: null, }, + { + type: GroupActivityType.SET_RESOLVED_BY_AGE, + id: 'set-resolved-by-age-2', + dateCreated: '2020-01-02T00:00:00', + data: {age: 11}, + user: null, + }, ], project, }); render(); - expect(await screen.findByText('Resolved')).toBeInTheDocument(); - expect(screen.getByText(/after 21 days of inactivity/)).toBeInTheDocument(); + expect(await screen.findByText(/after 21 days of inactivity/)).toBeInTheDocument(); + expect(screen.getByText(/after 11 hours of inactivity/)).toBeInTheDocument(); }); it('renders note and allows for edit', async () => { From 809392755190759d30be59e9dd61e6a5a08a70b3 Mon Sep 17 00:00:00 2001 From: Scott Cooper Date: Thu, 11 Jun 2026 15:41:24 -0700 Subject: [PATCH 4/5] fix(issues): Format auto-resolve age consistently --- .../activitySection/groupActivityItem.tsx | 24 +++++++++++++------ .../activitySection/index.spec.tsx | 8 +++++++ 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/static/app/views/issueDetails/activitySection/groupActivityItem.tsx b/static/app/views/issueDetails/activitySection/groupActivityItem.tsx index c0e3280115e342..903c61c6205ba8 100644 --- a/static/app/views/issueDetails/activitySection/groupActivityItem.tsx +++ b/static/app/views/issueDetails/activitySection/groupActivityItem.tsx @@ -22,6 +22,7 @@ import {GroupActivityType, IssueCategory as IssueCategoryEnum} from 'sentry/type import type {Organization, Team} from 'sentry/types/organization'; import type {Project} from 'sentry/types/project'; import type {User} from 'sentry/types/user'; +import {formatDuration} from 'sentry/utils/duration/formatDuration'; import {useOrganization} from 'sentry/utils/useOrganization'; import {isSemverRelease} from 'sentry/utils/versions/isSemverRelease'; @@ -288,13 +289,7 @@ export function getGroupActivityItem( }; } case GroupActivityType.SET_RESOLVED_BY_AGE: { - const age = activity.data.age; - const duration = - age && age >= 24 - ? tn('%s day', '%s days', Math.round(age / 24)) - : age - ? tn('%s hour', '%s hours', age) - : null; + const duration = formatAutoResolveAge(activity.data.age); return { title: t('Resolved'), message: duration @@ -798,6 +793,21 @@ export function getGroupActivityItem( return renderContent(); } +function formatAutoResolveAge(age: number | undefined) { + if (!age) { + return null; + } + + const precision = age > 23 && age % 24 === 0 ? 'day' : 'hour'; + const count = Number( + formatDuration({duration: [age, 'hour'], precision, style: 'count'}) + ); + + return precision === 'day' + ? tn('%s day', '%s days', count) + : tn('%s hour', '%s hours', count); +} + function ActivityRelease({project, version}: {project: Project; version: string}) { const organization = useOrganization(); return ( diff --git a/static/app/views/issueDetails/activitySection/index.spec.tsx b/static/app/views/issueDetails/activitySection/index.spec.tsx index ea68aa81aa5633..1e46f6968de557 100644 --- a/static/app/views/issueDetails/activitySection/index.spec.tsx +++ b/static/app/views/issueDetails/activitySection/index.spec.tsx @@ -364,6 +364,13 @@ describe('ActivitySection', () => { data: {age: 11}, user: null, }, + { + type: GroupActivityType.SET_RESOLVED_BY_AGE, + id: 'set-resolved-by-age-3', + dateCreated: '2020-01-03T00:00:00', + data: {age: 30}, + user: null, + }, ], project, }); @@ -372,6 +379,7 @@ describe('ActivitySection', () => { expect(await screen.findByText(/after 21 days of inactivity/)).toBeInTheDocument(); expect(screen.getByText(/after 11 hours of inactivity/)).toBeInTheDocument(); + expect(screen.getByText(/after 30 hours of inactivity/)).toBeInTheDocument(); }); it('renders note and allows for edit', async () => { From cc53fc84d6b5136cdcc2d57d2aa9175c8e64a565 Mon Sep 17 00:00:00 2001 From: Scott Cooper Date: Thu, 11 Jun 2026 15:47:37 -0700 Subject: [PATCH 5/5] fix(issues): Coerce auto-resolve activity age --- static/app/types/group.tsx | 2 +- .../issueDetails/activitySection/groupActivityItem.tsx | 9 +++++---- .../views/issueDetails/activitySection/index.spec.tsx | 8 ++++++++ 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/static/app/types/group.tsx b/static/app/types/group.tsx index 16f0bb309428df..14a60c63e02b9b 100644 --- a/static/app/types/group.tsx +++ b/static/app/types/group.tsx @@ -701,7 +701,7 @@ interface GroupActivitySetPrivate extends GroupActivityBase { interface GroupActivitySetByAge extends GroupActivityBase { data: { - age?: number; + age?: number | string; }; type: GroupActivityType.SET_RESOLVED_BY_AGE; } diff --git a/static/app/views/issueDetails/activitySection/groupActivityItem.tsx b/static/app/views/issueDetails/activitySection/groupActivityItem.tsx index 903c61c6205ba8..bbb20cc725dd40 100644 --- a/static/app/views/issueDetails/activitySection/groupActivityItem.tsx +++ b/static/app/views/issueDetails/activitySection/groupActivityItem.tsx @@ -793,14 +793,15 @@ export function getGroupActivityItem( return renderContent(); } -function formatAutoResolveAge(age: number | undefined) { - if (!age) { +function formatAutoResolveAge(age: number | string | undefined) { + const resolveAge = Number(age); + if (!Number.isFinite(resolveAge) || resolveAge <= 0) { return null; } - const precision = age > 23 && age % 24 === 0 ? 'day' : 'hour'; + const precision = resolveAge > 23 && resolveAge % 24 === 0 ? 'day' : 'hour'; const count = Number( - formatDuration({duration: [age, 'hour'], precision, style: 'count'}) + formatDuration({duration: [resolveAge, 'hour'], precision, style: 'count'}) ); return precision === 'day' diff --git a/static/app/views/issueDetails/activitySection/index.spec.tsx b/static/app/views/issueDetails/activitySection/index.spec.tsx index 1e46f6968de557..27cf8d22d80d8f 100644 --- a/static/app/views/issueDetails/activitySection/index.spec.tsx +++ b/static/app/views/issueDetails/activitySection/index.spec.tsx @@ -371,6 +371,13 @@ describe('ActivitySection', () => { data: {age: 30}, user: null, }, + { + type: GroupActivityType.SET_RESOLVED_BY_AGE, + id: 'set-resolved-by-age-4', + dateCreated: '2020-01-04T00:00:00', + data: {age: '48'}, + user: null, + }, ], project, }); @@ -380,6 +387,7 @@ describe('ActivitySection', () => { expect(await screen.findByText(/after 21 days of inactivity/)).toBeInTheDocument(); expect(screen.getByText(/after 11 hours of inactivity/)).toBeInTheDocument(); expect(screen.getByText(/after 30 hours of inactivity/)).toBeInTheDocument(); + expect(screen.getByText(/after 2 days of inactivity/)).toBeInTheDocument(); }); it('renders note and allows for edit', async () => {