teamStore.tsx 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. import Reflux from 'reflux';
  2. import TeamActions from 'app/actions/teamActions';
  3. import {Team} from 'app/types';
  4. type State = {
  5. teams: Team[];
  6. loading: boolean;
  7. hasMore: boolean | null;
  8. };
  9. type TeamStoreInterface = {
  10. initialized: boolean;
  11. state: State;
  12. reset: () => void;
  13. loadInitialData: (items: Team[], hasMore?: boolean | null) => void;
  14. onUpdateSuccess: (itemId: string, response: Team) => void;
  15. onRemoveSuccess: (slug: string) => void;
  16. onCreateSuccess: (team: Team) => void;
  17. get: () => State;
  18. getAll: () => Team[];
  19. getById: (id: string) => Team | null;
  20. getBySlug: (slug: string) => Team | null;
  21. };
  22. const teamStoreConfig: Reflux.StoreDefinition & TeamStoreInterface = {
  23. initialized: false,
  24. state: {
  25. teams: [],
  26. loading: true,
  27. hasMore: null,
  28. },
  29. init() {
  30. this.reset();
  31. this.listenTo(TeamActions.createTeamSuccess, this.onCreateSuccess);
  32. this.listenTo(TeamActions.fetchDetailsSuccess, this.onUpdateSuccess);
  33. this.listenTo(TeamActions.loadTeams, this.loadInitialData);
  34. this.listenTo(TeamActions.removeTeamSuccess, this.onRemoveSuccess);
  35. this.listenTo(TeamActions.updateSuccess, this.onUpdateSuccess);
  36. },
  37. reset() {
  38. this.state = {teams: [], loading: true, hasMore: null};
  39. },
  40. loadInitialData(items, hasMore = null) {
  41. this.initialized = true;
  42. this.state = {
  43. teams: items.sort((a, b) => a.slug.localeCompare(b.slug)),
  44. loading: false,
  45. hasMore,
  46. };
  47. this.trigger(new Set(items.map(item => item.id)));
  48. },
  49. onUpdateSuccess(itemId, response) {
  50. if (!response) {
  51. return;
  52. }
  53. const item = this.getBySlug(itemId);
  54. if (!item) {
  55. this.state = {
  56. ...this.state,
  57. teams: [...this.state.teams, response],
  58. };
  59. this.trigger(new Set([itemId]));
  60. return;
  61. }
  62. // Slug was changed
  63. // Note: This is the proper way to handle slug changes but unfortunately not all of our
  64. // components use stores correctly. To be safe reload browser :((
  65. if (response.slug !== itemId) {
  66. // Replace the team
  67. const teams = [...this.state.teams.filter(({slug}) => slug !== itemId), response];
  68. this.state = {...this.state, teams};
  69. this.trigger(new Set([response.slug]));
  70. return;
  71. }
  72. const newTeams = [...this.state.teams];
  73. const index = newTeams.findIndex(team => team.slug === response.slug);
  74. newTeams[index] = response;
  75. this.state = {...this.state, teams: newTeams};
  76. this.trigger(new Set([itemId]));
  77. },
  78. onRemoveSuccess(slug: string) {
  79. const {teams} = this.state;
  80. this.loadInitialData(teams.filter(team => team.slug !== slug));
  81. },
  82. onCreateSuccess(team: Team) {
  83. this.loadInitialData([...this.state.teams, team]);
  84. },
  85. get() {
  86. return this.state;
  87. },
  88. getById(id: string) {
  89. const {teams} = this.state;
  90. return teams.find(item => item.id.toString() === id.toString()) || null;
  91. },
  92. getBySlug(slug: string) {
  93. const {teams} = this.state;
  94. return teams.find(item => item.slug === slug) || null;
  95. },
  96. getAll() {
  97. return this.state.teams;
  98. },
  99. };
  100. const TeamStore = Reflux.createStore(teamStoreConfig) as Reflux.Store &
  101. TeamStoreInterface;
  102. export default TeamStore;