organizationsStore.tsx 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. import {createStore} from 'reflux';
  2. import type {Organization} from 'sentry/types/organization';
  3. import type {StrictStoreDefinition} from './types';
  4. interface State {
  5. loaded: boolean;
  6. organizations: Organization[];
  7. }
  8. interface OrganizationsStoreDefinition extends StrictStoreDefinition<State> {
  9. addOrReplace(item: Organization): void;
  10. get(slug: string): Organization | undefined;
  11. getAll(): Organization[];
  12. load(items: Organization[]): void;
  13. onChangeSlug(prev: Organization, next: Partial<Organization>): void;
  14. onRemoveSuccess(slug: string): void;
  15. onUpdate(org: Partial<Organization>): void;
  16. remove(slug: string): void;
  17. }
  18. const storeConfig: OrganizationsStoreDefinition = {
  19. state: {organizations: [], loaded: false},
  20. init() {
  21. // XXX: Do not use `this.listenTo` in this store. We avoid usage of reflux
  22. // listeners due to their leaky nature in tests.
  23. this.state = {organizations: [], loaded: false};
  24. },
  25. onUpdate(org) {
  26. let match = false;
  27. const newOrgs = [...this.state.organizations];
  28. newOrgs.forEach((existing, idx) => {
  29. if (existing.id === org.id) {
  30. newOrgs[idx] = {...existing, ...org};
  31. match = true;
  32. }
  33. });
  34. if (!match) {
  35. throw new Error(
  36. 'Cannot update an organization that is not in the OrganizationsStore'
  37. );
  38. }
  39. this.state = {...this.state, organizations: newOrgs};
  40. this.trigger(newOrgs);
  41. },
  42. onChangeSlug(prev, next) {
  43. if (prev.slug === next.slug) {
  44. return;
  45. }
  46. this.remove(prev.slug);
  47. this.addOrReplace({...prev, ...next});
  48. },
  49. onRemoveSuccess(slug) {
  50. this.remove(slug);
  51. },
  52. get(slug) {
  53. return this.state.organizations.find((item: Organization) => item.slug === slug);
  54. },
  55. getAll() {
  56. return this.state.organizations;
  57. },
  58. getState() {
  59. return this.state;
  60. },
  61. remove(slug) {
  62. this.state = {
  63. ...this.state,
  64. organizations: this.state.organizations.filter(item => slug !== item.slug),
  65. };
  66. this.trigger(this.state.organizations);
  67. },
  68. addOrReplace(item) {
  69. let match = false;
  70. const newOrgs = [...this.state.organizations];
  71. newOrgs.forEach((existing, idx) => {
  72. if (existing.id === item.id) {
  73. newOrgs[idx] = {...existing, ...item};
  74. match = true;
  75. }
  76. });
  77. if (!match) {
  78. newOrgs.push(item);
  79. }
  80. this.state = {...this.state, organizations: newOrgs};
  81. this.trigger(newOrgs);
  82. },
  83. load(items: Organization[]) {
  84. const newOrgs = [...items];
  85. this.state = {organizations: newOrgs, loaded: true};
  86. this.trigger(newOrgs);
  87. },
  88. };
  89. const OrganizationsStore = createStore(storeConfig);
  90. export default OrganizationsStore;