organizationStore.tsx 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. import {createStore} from 'reflux';
  2. import {ORGANIZATION_FETCH_ERROR_TYPES} from 'sentry/constants';
  3. import type {Organization} from 'sentry/types/organization';
  4. import type RequestError from 'sentry/utils/requestError/requestError';
  5. import HookStore from './hookStore';
  6. import LatestContextStore from './latestContextStore';
  7. import ReleaseStore from './releaseStore';
  8. import type {StrictStoreDefinition} from './types';
  9. type State = {
  10. dirty: boolean;
  11. loading: boolean;
  12. organization: Organization | null;
  13. error?: RequestError | null;
  14. errorType?: string | null;
  15. };
  16. interface OrganizationStoreDefinition extends StrictStoreDefinition<State> {
  17. get(): State;
  18. onFetchOrgError(err: RequestError): void;
  19. onUpdate(org: Organization, options?: {replace: true}): void;
  20. onUpdate(org: Partial<Organization>, options?: {replace?: false}): void;
  21. reset(): void;
  22. setNoOrganization(): void;
  23. }
  24. const storeConfig: OrganizationStoreDefinition = {
  25. state: {
  26. dirty: false,
  27. loading: true,
  28. organization: null,
  29. error: null,
  30. errorType: null,
  31. },
  32. init() {
  33. // XXX: Do not use `this.listenTo` in this store. We avoid usage of reflux
  34. // listeners due to their leaky nature in tests.
  35. this.reset();
  36. },
  37. reset() {
  38. this.state = {
  39. dirty: false,
  40. loading: true,
  41. organization: null,
  42. error: null,
  43. errorType: null,
  44. };
  45. this.trigger(this.get());
  46. },
  47. onUpdate(updatedOrg: Organization, {replace = false} = {}) {
  48. const organization = replace
  49. ? updatedOrg
  50. : {...this.state.organization, ...updatedOrg};
  51. this.state = {
  52. loading: false,
  53. dirty: false,
  54. errorType: null,
  55. error: null,
  56. organization,
  57. };
  58. this.trigger(this.get());
  59. ReleaseStore.updateOrganization(organization);
  60. LatestContextStore.onUpdateOrganization(organization);
  61. HookStore.getCallback(
  62. 'react-hook:route-activated',
  63. 'setOrganization'
  64. )?.(organization);
  65. },
  66. onFetchOrgError(err) {
  67. let errorType: State['errorType'] = null;
  68. switch (err?.status) {
  69. case 401:
  70. errorType = ORGANIZATION_FETCH_ERROR_TYPES.ORG_NO_ACCESS;
  71. break;
  72. case 404:
  73. errorType = ORGANIZATION_FETCH_ERROR_TYPES.ORG_NOT_FOUND;
  74. break;
  75. default:
  76. }
  77. this.state = {
  78. errorType,
  79. dirty: false,
  80. error: err,
  81. loading: false,
  82. organization: null,
  83. };
  84. this.trigger(this.get());
  85. },
  86. setNoOrganization() {
  87. this.state = {
  88. ...this.state,
  89. organization: null,
  90. errorType: ORGANIZATION_FETCH_ERROR_TYPES.NO_ORGS,
  91. loading: false,
  92. dirty: false,
  93. };
  94. this.trigger(this.get());
  95. },
  96. get() {
  97. return this.state;
  98. },
  99. getState() {
  100. return this.state;
  101. },
  102. };
  103. const OrganizationStore = createStore(storeConfig);
  104. export default OrganizationStore;