Skip to content

ref(releases): Convert ReleaseIssues to functional component#115698

Draft
ryan953 wants to merge 4 commits into
masterfrom
ryan953/ref/remove-browser-history-release-issues
Draft

ref(releases): Convert ReleaseIssues to functional component#115698
ryan953 wants to merge 4 commits into
masterfrom
ryan953/ref/remove-browser-history-release-issues

Conversation

@ryan953
Copy link
Copy Markdown
Member

@ryan953 ryan953 commented May 16, 2026

Convert the ReleaseIssues class component to a functional component, removing the browserHistory shim import.

Hooks replace HOCs and shim

withApi, withOrganization, and browserHistory are replaced with useApi, useOrganization, and useNavigate hooks respectively. useLocation replaces the location prop. The component's public API shrinks to just version, releaseBounds, queryFilterDescription, and withChart.

Test updates

Tests now use initialRouterConfig and organization render options instead of passing location and organization as props. Manual rerender calls for location changes are replaced by relying on the component's own navigate() call triggered by user interaction.

View Interactive Review

Replace browserHistory with useNavigate, remove withApi/withOrganization
HOCs in favor of useApi/useOrganization hooks.
@github-actions github-actions Bot added the Scope: Frontend Automatically applied to PRs that change frontend components label May 16, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 16, 2026

📊 Type Coverage Diff

Metric Before After Delta
Coverage 93.53% 93.53% ±0%
Typed 135,645 135,639 🔴 -6
Untyped 9,388 9,386 🟢 -2
🔍 3 new type safety issues introduced

any-typed symbols (2 new)

File Line Detail
static/app/views/explore/releases/detail/overview/releaseIssues.tsx 266 handleFetchSuccess (var)
static/app/views/explore/releases/detail/overview/releaseIssues.tsx 266 cursorFn (param)

Type assertions (as) (1 new)

File Line Detail
static/app/views/explore/releases/detail/overview/releaseIssues.tsx 56 as stringlocation.query?.issuesType as string

This is informational only and does not block the PR.

</DemoTourElement>
)}
<ReleaseIssues
organization={organization}
Copy link
Copy Markdown
Member Author

@ryan953 ryan953 May 16, 2026

Choose a reason for hiding this comment

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

weird. it also had withOrganization() wrapping it before.

Comment on lines +56 to +61
function getActiveIssuesType(location: ReturnType<typeof useLocation>): IssuesType {
const query = (location.query?.issuesType as string) ?? '';
return Object.values<string>(IssuesType).includes(query)
? (query as IssuesType)
: IssuesType.NEW;
}
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

straight up moved out of the old component, but changed this.props.location to a arg 👍

Comment on lines +63 to +71
function getIssuesEndpoint(
version: string,
location: ReturnType<typeof useLocation>,
releaseBounds: ReleaseBounds,
issuesType: IssuesType
): {
endpoint: React.ComponentProps<typeof GroupList>['endpoint'];
queryParams: IssuesQueryParams;
} {
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

straight up moved. Replace member calls to be function args

this is gone:

const {version, location, releaseBounds} = this.props;
const issuesType = this.getActiveIssuesType();

now we have args!

Move getIssuesUrl out of the component body to match the pattern
of getActiveIssuesType and getIssuesEndpoint.
Comment on lines +147 to +155
function getIssuesUrl(
version: string,
location: ReturnType<typeof useLocation>,
releaseBounds: ReleaseBounds,
issuesType: IssuesType,
organizationSlug: string
) {
const {queryParams} = getIssuesEndpoint(version, location, releaseBounds, issuesType);
const query = new MutableSearch([]);
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

another straight up move, with args passed.

previously:

const {version, organization} = this.props;
const issuesType = this.getActiveIssuesType();
const {queryParams} = this.getIssuesEndpoint();
const query = new MutableSearch([]);

Use apiOptions + useQuery for the issues-count and resolved endpoints
instead of manual api.requestPromise with useCallback/useEffect.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scope: Frontend Automatically applied to PRs that change frontend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant