messagingIntegrationModal.tsx 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. import {Fragment} from 'react';
  2. import styled from '@emotion/styled';
  3. import {addErrorMessage} from 'sentry/actionCreators/indicator';
  4. import type {ModalRenderProps} from 'sentry/actionCreators/modal';
  5. import {t} from 'sentry/locale';
  6. import {space} from 'sentry/styles/space';
  7. import type {IntegrationProvider} from 'sentry/types/integrations';
  8. import type {Project} from 'sentry/types/project';
  9. import {useApiQueries} from 'sentry/utils/queryClient';
  10. import useOrganization from 'sentry/utils/useOrganization';
  11. import AddIntegrationRow from 'sentry/views/alerts/rules/issue/addIntegrationRow';
  12. import {IntegrationContext} from 'sentry/views/settings/organizationIntegrations/integrationContext';
  13. type Props = ModalRenderProps & {
  14. headerContent: React.ReactNode;
  15. project: Project;
  16. providerKeys: string[];
  17. bodyContent?: React.ReactNode;
  18. onAddIntegration?: () => void;
  19. };
  20. function MessagingIntegrationModal({
  21. closeModal,
  22. Header,
  23. Body,
  24. headerContent,
  25. bodyContent,
  26. providerKeys,
  27. project,
  28. onAddIntegration,
  29. }: Props) {
  30. const organization = useOrganization();
  31. const queryResults = useApiQueries<{providers: IntegrationProvider[]}>(
  32. providerKeys.map((providerKey: string) => [
  33. `/organizations/${organization.slug}/config/integrations/?provider_key=${providerKey}`,
  34. ]),
  35. {staleTime: Infinity}
  36. );
  37. if (queryResults.some(({isLoading}) => isLoading)) {
  38. return null;
  39. }
  40. if (queryResults.some(({isError}) => isError)) {
  41. closeModal();
  42. addErrorMessage(t('Failed to load integration data'));
  43. return null;
  44. }
  45. return (
  46. <Fragment>
  47. <Header closeButton>
  48. <h1>{headerContent}</h1>
  49. </Header>
  50. <Body>
  51. <p>{bodyContent}</p>
  52. <IntegrationsWrapper>
  53. {queryResults.map(result => {
  54. const provider = result.data?.providers[0];
  55. if (!provider) {
  56. return null;
  57. }
  58. return (
  59. <IntegrationContext.Provider
  60. key={provider.key}
  61. value={{
  62. provider: provider,
  63. type: 'first_party',
  64. installStatus: 'Not Installed',
  65. analyticsParams: {
  66. already_installed: false,
  67. view: 'messaging_integration_onboarding',
  68. },
  69. onAddIntegration: onAddIntegration,
  70. modalParams: {projectId: project.id},
  71. }}
  72. >
  73. <AddIntegrationRow onClick={closeModal} />
  74. </IntegrationContext.Provider>
  75. );
  76. })}
  77. </IntegrationsWrapper>
  78. </Body>
  79. </Fragment>
  80. );
  81. }
  82. const IntegrationsWrapper = styled('div')`
  83. display: flex;
  84. flex-direction: column;
  85. gap: ${space(2)};
  86. `;
  87. export default MessagingIntegrationModal;