withSentryAppComponents.tsx 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. import {Component} from 'react';
  2. import SentryAppComponentsStore from 'sentry/stores/sentryAppComponentsStore';
  3. import {SentryAppComponent} from 'sentry/types';
  4. import getDisplayName from 'sentry/utils/getDisplayName';
  5. type InjectedAppComponentsProps = {
  6. components: SentryAppComponent[];
  7. };
  8. type State = {
  9. components: SentryAppComponent[];
  10. };
  11. type Options = {
  12. componentType?: SentryAppComponent['type'];
  13. };
  14. function withSentryAppComponents<P extends InjectedAppComponentsProps>(
  15. WrappedComponent: React.ComponentType<P>,
  16. {componentType}: Options = {}
  17. ) {
  18. class WithSentryAppComponents extends Component<
  19. Omit<P, keyof InjectedAppComponentsProps> & Partial<InjectedAppComponentsProps>,
  20. State
  21. > {
  22. static displayName = `withSentryAppComponents(${getDisplayName(WrappedComponent)})`;
  23. state = {components: SentryAppComponentsStore.getAll()};
  24. componentWillUnmount() {
  25. this.unsubscribe();
  26. }
  27. unsubscribe = SentryAppComponentsStore.listen(
  28. () => this.setState({components: SentryAppComponentsStore.getAll()}),
  29. undefined
  30. );
  31. render() {
  32. const {components: propComponents, ...props} = this.props as P;
  33. const storeComponents = componentType
  34. ? this.state.components.filter(item => item.type === componentType)
  35. : this.state.components;
  36. const components = propComponents ?? storeComponents;
  37. return <WrappedComponent {...({components, ...props} as P)} />;
  38. }
  39. }
  40. return WithSentryAppComponents;
  41. }
  42. export default withSentryAppComponents;