messagingIntegrationAlertRule.tsx 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. import {useMemo} from 'react';
  2. import styled from '@emotion/styled';
  3. import SelectControl from 'sentry/components/forms/controls/selectControl';
  4. import Input from 'sentry/components/input';
  5. import {t} from 'sentry/locale';
  6. import {space} from 'sentry/styles/space';
  7. import {
  8. type IssueAlertNotificationProps,
  9. providerDetails,
  10. } from 'sentry/views/projectInstall/issueAlertNotificationOptions';
  11. export default function MessagingIntegrationAlertRule({
  12. channel,
  13. integration,
  14. provider,
  15. setChannel,
  16. setIntegration,
  17. setProvider,
  18. providersToIntegrations,
  19. }: IssueAlertNotificationProps) {
  20. const providerOptions = useMemo(
  21. () =>
  22. Object.keys(providersToIntegrations).map(p => ({
  23. value: p,
  24. label: providerDetails[p].name,
  25. })),
  26. [providersToIntegrations]
  27. );
  28. const integrationOptions = useMemo(
  29. () =>
  30. provider && providersToIntegrations[provider]
  31. ? providersToIntegrations[provider]?.map(i => ({
  32. value: i,
  33. label: i.name,
  34. }))
  35. : [],
  36. [providersToIntegrations, provider]
  37. );
  38. if (!provider) {
  39. return null;
  40. }
  41. return (
  42. <Rule>
  43. {providerDetails[provider]?.makeSentence({
  44. providerName: (
  45. <InlineSelectControl
  46. aria-label={t('provider')}
  47. disabled={Object.keys(providersToIntegrations).length === 1}
  48. value={provider}
  49. options={providerOptions}
  50. onChange={p => {
  51. setProvider(p.value);
  52. setIntegration(providersToIntegrations[p.value][0]);
  53. setChannel('');
  54. }}
  55. />
  56. ),
  57. integrationName: (
  58. <InlineSelectControl
  59. aria-label={t('integration')}
  60. disabled={integrationOptions.length === 1}
  61. value={integration}
  62. options={integrationOptions}
  63. onChange={i => setIntegration(i.value)}
  64. />
  65. ),
  66. target: (
  67. <InlineInput
  68. aria-label={t('channel')}
  69. type="text"
  70. value={channel || ''}
  71. placeholder={providerDetails[provider]?.placeholder}
  72. onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
  73. setChannel(e.target.value)
  74. }
  75. />
  76. ),
  77. })}
  78. </Rule>
  79. );
  80. }
  81. const Rule = styled('div')`
  82. padding: ${space(1)};
  83. background-color: ${p => p.theme.backgroundSecondary};
  84. border-radius: ${p => p.theme.borderRadius};
  85. display: flex;
  86. align-items: center;
  87. gap: ${space(1)};
  88. `;
  89. const InlineSelectControl = styled(SelectControl)`
  90. width: 180px;
  91. `;
  92. const InlineInput = styled(Input)`
  93. width: auto;
  94. min-height: 28px;
  95. `;