organizationStore.tsx 2.7 KB

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