organizationStore.tsx 2.7 KB

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