latestContextStore.tsx 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. import {createStore, StoreDefinition} from 'reflux';
  2. import {Organization, Project} from 'sentry/types';
  3. type State = {
  4. environment: string | string[] | null;
  5. lastProject: Project | null;
  6. organization: Organization | null;
  7. project: Project | null;
  8. };
  9. interface LatestContextStoreDefinition extends StoreDefinition {
  10. get(): State;
  11. onSetActiveOrganization(organization: Organization): void;
  12. onSetActiveProject(project: Project | null): void;
  13. onUpdateOrganization(organization: Partial<Organization>): void;
  14. onUpdateProject(project: Project | null): void;
  15. reset(): void;
  16. state: State;
  17. }
  18. /**
  19. * Keeps track of last usable project/org this currently won't track when users
  20. * navigate out of a org/project completely, it tracks only if a user switches
  21. * into a new org/project.
  22. *
  23. * Only keep slug so that people don't get the idea to access org/project data
  24. * here Org/project data is currently in organizationsStore/projectsStore
  25. */
  26. const storeConfig: LatestContextStoreDefinition = {
  27. state: {
  28. project: null,
  29. lastProject: null,
  30. organization: null,
  31. environment: null,
  32. },
  33. get() {
  34. return this.state;
  35. },
  36. init() {
  37. // XXX: Do not use `this.listenTo` in this store. We avoid usage of reflux
  38. // listeners due to their leaky nature in tests.
  39. this.reset();
  40. },
  41. reset() {
  42. this.state = {
  43. project: null,
  44. lastProject: null,
  45. organization: null,
  46. environment: null,
  47. };
  48. return this.state;
  49. },
  50. onUpdateOrganization(org) {
  51. // Don't do anything if base/target orgs are falsey
  52. if (!this.state.organization) {
  53. return;
  54. }
  55. if (!org) {
  56. return;
  57. }
  58. // Check to make sure current active org is what has been updated
  59. if (org.slug !== this.state.organization.slug) {
  60. return;
  61. }
  62. this.state = {
  63. ...this.state,
  64. organization: {...this.state.organization, ...org},
  65. };
  66. this.trigger(this.state);
  67. },
  68. onSetActiveOrganization(org) {
  69. if (!org) {
  70. this.state = {
  71. ...this.state,
  72. organization: null,
  73. project: null,
  74. };
  75. } else if (!this.state.organization || this.state.organization.slug !== org.slug) {
  76. // Update only if different
  77. this.state = {
  78. ...this.state,
  79. organization: org,
  80. project: null,
  81. };
  82. }
  83. this.trigger(this.state);
  84. },
  85. onSetActiveProject(project) {
  86. if (!project) {
  87. this.state = {
  88. ...this.state,
  89. lastProject: this.state.project,
  90. project: null,
  91. };
  92. } else if (!this.state.project || this.state.project.slug !== project.slug) {
  93. // Update only if different
  94. this.state = {
  95. ...this.state,
  96. lastProject: this.state.project,
  97. project,
  98. };
  99. }
  100. this.trigger(this.state);
  101. },
  102. onUpdateProject(project) {
  103. this.state = {
  104. ...this.state,
  105. project,
  106. };
  107. this.trigger(this.state);
  108. },
  109. };
  110. const LatestContextStore = createStore(storeConfig);
  111. export default LatestContextStore;