123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- import {ExternalIssueComponent} from 'sentry/components/group/externalIssuesList/types';
- import useIssueTrackingFilter from 'sentry/components/group/externalIssuesList/useIssueTrackingFilter';
- import SentryAppInstallationStore from 'sentry/stores/sentryAppInstallationsStore';
- import {useLegacyStore} from 'sentry/stores/useLegacyStore';
- import type {Group, Project} from 'sentry/types';
- import type {Event} from 'sentry/types/event';
- import useOrganization from 'sentry/utils/useOrganization';
- import useSentryAppComponentsStore from 'sentry/utils/useSentryAppComponentsStore';
- type Props = {
- event: Event;
- group: Group;
- project: Project;
- };
- export default function useExternalIssueData({group, event, project}: Props) {
- const organization = useOrganization();
- const issueTrackingFilter = useIssueTrackingFilter();
- const components = useSentryAppComponentsStore({componentType: 'issue-link'});
- const sentryAppInstallations = useLegacyStore(SentryAppInstallationStore);
- const renderSentryAppIssues = (): ExternalIssueComponent[] => {
- return components
- .map<ExternalIssueComponent | null>(component => {
- const {sentryApp, error: disabled} = component;
- const installation = sentryAppInstallations.find(
- i => i.app.uuid === sentryApp.uuid
- );
- // should always find a match but TS complains if we don't handle this case
- if (!installation) {
- return null;
- }
- const issue = (group.sentryAppIssues || []).find(
- i => i.serviceType === sentryApp.slug
- );
- return {
- type: 'sentry-app-issue',
- key: sentryApp.slug,
- disabled,
- hasLinkedIssue: !!issue,
- props: {
- sentryApp,
- group,
- organization,
- event,
- sentryAppComponent: component,
- sentryAppInstallation: installation,
- externalIssue: issue,
- disabled,
- },
- };
- })
- .filter((x): x is ExternalIssueComponent => x !== null);
- };
- const renderIntegrationIssues = (): ExternalIssueComponent[] => {
- return (
- group.integrationIssues?.map(issue => ({
- type: 'integration-issue',
- key: issue.key,
- disabled: false,
- hasLinkedIssue: true,
- props: {
- configurations: [],
- externalIssue: issue,
- group,
- onChange: () => {},
- },
- })) ?? []
- );
- };
- const renderPluginIssues = (): ExternalIssueComponent[] => {
- return group.pluginIssues?.map((plugin, i) => ({
- type: 'plugin-issue',
- key: `plugin-issue-${i}`,
- disabled: false,
- hasLinkedIssue: true,
- props: {
- group,
- project,
- plugin,
- },
- }));
- };
- const renderPluginActions = (): ExternalIssueComponent[] => {
- return (
- group.pluginActions?.map((plugin, i) => ({
- type: 'plugin-action',
- key: `plugin-action-${i}`,
- disabled: false,
- hasLinkedIssue: false,
- props: {plugin},
- })) ?? []
- );
- };
- const linkedIssues = [
- ...renderSentryAppIssues(),
- ...renderIntegrationIssues(),
- ...renderPluginIssues(),
- ...renderPluginActions(),
- ].filter(issue => !issueTrackingFilter || issue.key === issueTrackingFilter);
- // Plugins: need to do some extra logic to detect if the issue is linked,
- // by checking if there exists an issue object
- const plugins = linkedIssues.filter(
- a =>
- (a.type === 'plugin-issue' || a.type === 'plugin-action') &&
- 'issue' in a.props.plugin
- );
- // Sentry app issues: read from `hasLinkedIssue` property
- const sentryAppIssues = linkedIssues.filter(
- a =>
- a.hasLinkedIssue &&
- a.type === 'sentry-app-issue' &&
- a.props.externalIssue?.issueId === group.id
- );
- // Integration issues
- const integrationIssues = linkedIssues.filter(a => a.type === 'integration-issue');
- return {linkedIssues: plugins.concat(integrationIssues).concat(sentryAppIssues)};
- }
|