resourceSubscriptions.tsx 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. import {Component, Fragment} from 'react';
  2. import styled from '@emotion/styled';
  3. import FormContext from 'sentry/components/forms/formContext';
  4. import type {Permissions, WebhookEvent} from 'sentry/types';
  5. import {
  6. EVENT_CHOICES,
  7. PERMISSIONS_MAP,
  8. } from 'sentry/views/settings/organizationDeveloperSettings/constants';
  9. import SubscriptionBox from 'sentry/views/settings/organizationDeveloperSettings/subscriptionBox';
  10. type Resource = (typeof EVENT_CHOICES)[number];
  11. type DefaultProps = {
  12. webhookDisabled: boolean;
  13. };
  14. type Props = DefaultProps & {
  15. events: WebhookEvent[];
  16. onChange: (events: WebhookEvent[]) => void;
  17. permissions: Permissions;
  18. };
  19. export default class Subscriptions extends Component<Props> {
  20. static defaultProps: DefaultProps = {
  21. webhookDisabled: false,
  22. };
  23. constructor(props: Props, context) {
  24. super(props, context);
  25. this.context.form.setValue('events', this.props.events);
  26. }
  27. componentDidUpdate(prevProps: Props) {
  28. const {webhookDisabled, permissions, events} = this.props;
  29. const permittedEvents = events.filter(
  30. resource => permissions[PERMISSIONS_MAP[resource]] !== 'no-access'
  31. );
  32. // When disabling webhooks unset the events
  33. if (!prevProps.webhookDisabled && webhookDisabled && prevProps.events.length) {
  34. this.save([]);
  35. return;
  36. }
  37. if (JSON.stringify(events) !== JSON.stringify(permittedEvents)) {
  38. this.save(permittedEvents);
  39. }
  40. }
  41. declare context: Required<React.ContextType<typeof FormContext>>;
  42. static contextType = FormContext;
  43. onChange = (resource: Resource, checked: boolean) => {
  44. const events = new Set(this.props.events);
  45. checked ? events.add(resource) : events.delete(resource);
  46. this.save(Array.from(events));
  47. };
  48. save = (events: WebhookEvent[]) => {
  49. this.props.onChange(events);
  50. this.context.form.setValue('events', events);
  51. };
  52. render() {
  53. const {permissions, webhookDisabled, events} = this.props;
  54. return (
  55. <SubscriptionGrid>
  56. {EVENT_CHOICES.map(choice => {
  57. const disabledFromPermissions =
  58. permissions[PERMISSIONS_MAP[choice]] === 'no-access';
  59. return (
  60. <Fragment key={choice}>
  61. <SubscriptionBox
  62. key={choice}
  63. disabledFromPermissions={disabledFromPermissions}
  64. webhookDisabled={webhookDisabled}
  65. checked={events.includes(choice) && !disabledFromPermissions}
  66. resource={choice}
  67. onChange={this.onChange}
  68. isNew={false}
  69. />
  70. </Fragment>
  71. );
  72. })}
  73. </SubscriptionGrid>
  74. );
  75. }
  76. }
  77. const SubscriptionGrid = styled('div')`
  78. display: grid;
  79. grid-template: auto / 1fr 1fr 1fr;
  80. @media (max-width: ${props => props.theme.breakpoints.large}) {
  81. grid-template: 1fr 1fr 1fr / auto;
  82. }
  83. `;