organizationsStore.tsx 2.3 KB

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