import * as React from 'react'; import createReactClass from 'create-react-class'; import Reflux from 'reflux'; import {fetchPlugins} from 'app/actionCreators/plugins'; import PluginsStore from 'app/stores/pluginsStore'; import {Organization, Plugin, Project} from 'app/types'; import {defined} from 'app/utils'; import getDisplayName from 'app/utils/getDisplayName'; import withOrganization from 'app/utils/withOrganization'; import withProject from 'app/utils/withProject'; type WithPluginProps = { organization: Organization; project?: Project; }; type InjectedPluginProps = { plugins: {plugins: Plugin[]; loading: boolean}; }; /** * Higher order component that fetches list of plugins and * passes PluginsStore to component as `plugins` */ const withPlugins =

( WrappedComponent: React.ComponentType

) => withOrganization( withProject( createReactClass & WithPluginProps, {}>({ displayName: `withPlugins(${getDisplayName(WrappedComponent)})`, mixins: [Reflux.connect(PluginsStore, 'store') as any], componentDidMount() { this.fetchPlugins(); }, componentDidUpdate(prevProps, _prevState, prevContext) { const {organization, project} = this.props; // Only fetch plugins when a org slug or project slug has changed const prevOrg = prevProps.organization || (prevContext && prevContext.organization); const prevProject = prevProps.project || (prevContext && prevContext.project); // If previous org/project is undefined then it means: // the HoC has mounted, `fetchPlugins` has been called (via cDM), and // store was updated. We don't need to fetchPlugins again (or it will cause an infinite loop) // // This is for the unusual case where component is mounted and receives a new org/project prop // e.g. when switching projects via breadcrumbs in settings. if (!defined(prevProject) || !defined(prevOrg)) { return; } const isOrgSame = prevOrg.slug === organization.slug; const isProjectSame = prevProject.slug === project?.slug; // Don't do anything if org and project are the same if (isOrgSame && isProjectSame) { return; } this.fetchPlugins(); }, fetchPlugins() { const {organization, project} = this.props; if (!project || !organization) { return; } fetchPlugins({projectId: project.slug, orgId: organization.slug}); }, render() { return ( ); }, }) ) ); export default withPlugins;