organizationSettingsNavigation.tsx 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. import {Component} from 'react';
  2. import ConfigStore from 'sentry/stores/configStore';
  3. import HookStore from 'sentry/stores/hookStore';
  4. import type {HookName, Hooks} from 'sentry/types/hooks';
  5. import type {Organization} from 'sentry/types/organization';
  6. import withOrganization from 'sentry/utils/withOrganization';
  7. import SettingsNavigation from 'sentry/views/settings/components/settingsNavigation';
  8. import navigationConfiguration from 'sentry/views/settings/organization/navigationConfiguration';
  9. import type {NavigationSection} from 'sentry/views/settings/types';
  10. type Props = {
  11. organization: Organization;
  12. };
  13. type State = {
  14. hookConfigs: NavigationSection[];
  15. hooks: React.ReactElement[];
  16. };
  17. class OrganizationSettingsNavigation extends Component<Props, State> {
  18. state: State = this.getHooks();
  19. componentDidMount() {
  20. // eslint-disable-next-line react/no-did-mount-set-state
  21. this.setState(this.getHooks());
  22. }
  23. componentWillUnmount() {
  24. this.unsubscribe();
  25. }
  26. /**
  27. * TODO(epurkhiser): Becase the settings organization navigation hooks
  28. * do not conform to a normal component style hook, and take a single
  29. * parameter 'organization', we cannot use the `Hook` component here,
  30. * and must resort to using listening to the HookStore to retrieve hook data.
  31. *
  32. * We should update the hook interface for the two hooks used here
  33. */
  34. unsubscribe = HookStore.listen(
  35. (hookName: HookName, hooks: Hooks['settings:organization-navigation-config'][]) => {
  36. this.handleHooks(hookName, hooks);
  37. },
  38. undefined
  39. );
  40. getHooks() {
  41. // Allow injection via getsentry et all
  42. const {organization} = this.props as Props;
  43. return {
  44. hookConfigs: HookStore.get('settings:organization-navigation-config').map(cb =>
  45. cb(organization)
  46. ),
  47. hooks: HookStore.get('settings:organization-navigation').map(cb =>
  48. cb(organization)
  49. ),
  50. };
  51. }
  52. handleHooks(name: HookName, hooks: Hooks['settings:organization-navigation-config'][]) {
  53. const org = this.props.organization;
  54. if (name !== 'settings:organization-navigation-config') {
  55. return;
  56. }
  57. this.setState({hookConfigs: hooks.map(cb => cb(org))});
  58. }
  59. render() {
  60. const {hooks, hookConfigs} = this.state as State;
  61. const {organization} = this.props as Props;
  62. const access = new Set(organization.access);
  63. const features = new Set(organization.features);
  64. const isSelfHosted = ConfigStore.get('isSelfHosted');
  65. return (
  66. <SettingsNavigation
  67. navigationObjects={navigationConfiguration}
  68. access={access}
  69. features={features}
  70. organization={organization}
  71. hooks={hooks}
  72. hookConfigs={hookConfigs}
  73. isSelfHosted={isSelfHosted}
  74. />
  75. );
  76. }
  77. }
  78. export default withOrganization(OrganizationSettingsNavigation);