organizationsStore.tsx 2.6 KB

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