withSdkUpdates.tsx 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. import * as React from 'react';
  2. import {loadSdkUpdates} from 'sentry/actionCreators/sdkUpdates';
  3. import {Client} from 'sentry/api';
  4. import SdkUpdatesStore from 'sentry/stores/sdkUpdatesStore';
  5. import {Organization, ProjectSdkUpdates} from 'sentry/types';
  6. import withApi from './withApi';
  7. import withOrganization from './withOrganization';
  8. type InjectedProps = {
  9. /**
  10. * List of (Project + SDK)s and potential update suggestions for each.
  11. *
  12. * Null when updates have not been loaded for this org.
  13. */
  14. sdkUpdates?: ProjectSdkUpdates[] | null;
  15. };
  16. type Props = {
  17. api: Client;
  18. organization: Organization;
  19. /**
  20. * Project IDs to limit the updates query to
  21. */
  22. projectIds?: string[];
  23. };
  24. type State = {
  25. sdkUpdates: ProjectSdkUpdates[] | null;
  26. };
  27. function withSdkUpdates<P extends InjectedProps>(
  28. WrappedComponent: React.ComponentType<P>
  29. ) {
  30. class WithProjectSdkSuggestions extends React.Component<
  31. Omit<P, keyof InjectedProps> & Props,
  32. State
  33. > {
  34. state: State = {sdkUpdates: []};
  35. componentDidMount() {
  36. const orgSlug = this.props.organization.slug;
  37. const updates = SdkUpdatesStore.getUpdates(orgSlug);
  38. // Load SdkUpdates
  39. if (updates !== undefined) {
  40. this.onSdkUpdatesUpdate();
  41. return;
  42. }
  43. loadSdkUpdates(this.props.api, orgSlug);
  44. }
  45. componentWillUnmount() {
  46. this.unsubscribe();
  47. }
  48. unsubscribe = SdkUpdatesStore.listen(() => this.onSdkUpdatesUpdate(), undefined);
  49. onSdkUpdatesUpdate() {
  50. const sdkUpdates = SdkUpdatesStore.getUpdates(this.props.organization.slug) ?? null;
  51. this.setState({sdkUpdates});
  52. }
  53. render() {
  54. // TODO(ts) This unknown cast isn't great but Typescript complains about arbitrary
  55. // types being possible. I think this is related to the additional HoC wrappers causing type data to
  56. // be lost.
  57. return (
  58. <WrappedComponent
  59. {...(this.props as unknown as P)}
  60. sdkUpdates={this.state.sdkUpdates}
  61. />
  62. );
  63. }
  64. }
  65. return withOrganization(withApi(WithProjectSdkSuggestions));
  66. }
  67. export default withSdkUpdates;