import {Component} from 'react'; import ConfigStore from 'sentry/stores/configStore'; import LatestContextStore from 'sentry/stores/latestContextStore'; import {Organization, OrganizationSummary, Project} from 'sentry/types'; import getDisplayName from 'sentry/utils/getDisplayName'; import withOrganizations from 'sentry/utils/withOrganizations'; type InjectedLatestContextProps = { organization?: Organization | null; organizations?: OrganizationSummary[]; project?: Project | null; }; type HocProps = { organizations: OrganizationSummary[]; organization?: Organization | null; }; type State = { latestContext: Omit; }; const fallbackContext: State['latestContext'] = { organization: null, project: null, }; function withLatestContext

( WrappedComponent: React.ComponentType

) { class WithLatestContext extends Component< Omit & HocProps, State > { static displayName = `withLatestContext(${getDisplayName(WrappedComponent)})`; state: State = { latestContext: LatestContextStore.get(), }; componentWillUmount() { this.unsubscribe(); } unsubscribe = LatestContextStore.listen( (latestContext: State['latestContext']) => this.setState({latestContext}), undefined ); render() { const {organizations} = this.props; const {latestContext} = this.state; const {organization, project} = latestContext || fallbackContext; // Even though org details exists in LatestContextStore, // fetch organization from OrganizationsStore so that we can // expect consistent data structure because OrganizationsStore has a list // of orgs but not full org details const latestOrganization = organization || (organizations && organizations.length ? organizations.find( ({slug}) => slug === ConfigStore.get('lastOrganization') ) || organizations[0] : null); // TODO(billy): Below is going to be wrong if component is passed project, it will override // project from `latestContext` return ( ); } } return withOrganizations(WithLatestContext); } export default withLatestContext;