withSentryAppComponents.tsx 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  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?: 'stacktrace-link';
  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, ...props} = this.props as P;
  33. return (
  34. <WrappedComponent
  35. {...({
  36. components:
  37. components ?? SentryAppComponentsStore.getComponentByType(componentType),
  38. ...props,
  39. } as P)}
  40. />
  41. );
  42. }
  43. }
  44. return WithSentryAppComponents;
  45. }
  46. export default withSentryAppComponents;