projectsStatsStore.tsx 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. import {createStore, StoreDefinition} from 'reflux';
  2. import {Project} from 'sentry/types';
  3. interface ProjectsStatsStoreDefinition extends StoreDefinition {
  4. getAll(): ProjectsStatsStoreDefinition['itemsBySlug'];
  5. getBySlug(slug: string): Project;
  6. getInitialState(): ProjectsStatsStoreDefinition['itemsBySlug'];
  7. itemsBySlug: Record<string, Project>;
  8. onStatsLoadSuccess(projects: Project[]): void;
  9. onUpdate(projectSlug: string, data: Partial<Project>): void;
  10. onUpdateError(err: Error, projectSlug: string): void;
  11. reset(): void;
  12. }
  13. /**
  14. * This is a store specifically used by the dashboard, so that we can
  15. * clear the store when the Dashboard unmounts
  16. * (as to not disrupt ProjectsStore which a lot more components use)
  17. */
  18. const storeConfig: ProjectsStatsStoreDefinition = {
  19. itemsBySlug: {},
  20. init() {
  21. this.reset();
  22. },
  23. getInitialState() {
  24. return this.itemsBySlug;
  25. },
  26. reset() {
  27. this.itemsBySlug = {};
  28. this.updatingItems = new Map();
  29. },
  30. onStatsLoadSuccess(projects) {
  31. projects.forEach(project => {
  32. this.itemsBySlug[project.slug] = project;
  33. });
  34. this.trigger(this.itemsBySlug);
  35. },
  36. /**
  37. * Optimistic updates
  38. * @param projectSlug Project slug
  39. * @param data Project data
  40. */
  41. onUpdate(projectSlug, data) {
  42. const project = this.getBySlug(projectSlug);
  43. this.updatingItems.set(projectSlug, project);
  44. if (!project) {
  45. return;
  46. }
  47. const newProject: Project = {
  48. ...project,
  49. ...data,
  50. };
  51. this.itemsBySlug = {
  52. ...this.itemsBySlug,
  53. [project.slug]: newProject,
  54. };
  55. this.trigger(this.itemsBySlug);
  56. },
  57. onUpdateSuccess(data: Project) {
  58. // Remove project from updating map
  59. this.updatingItems.delete(data.slug);
  60. },
  61. /**
  62. * Revert project data when there was an error updating project details
  63. * @param err Error object
  64. * @param data Previous project data
  65. */
  66. onUpdateError(_err, projectSlug) {
  67. const project = this.updatingItems.get(projectSlug);
  68. if (!project) {
  69. return;
  70. }
  71. this.updatingItems.delete(projectSlug);
  72. // Restore old project
  73. this.itemsBySlug = {
  74. ...this.itemsBySlug,
  75. [project.slug]: {...project},
  76. };
  77. this.trigger(this.itemsBySlug);
  78. },
  79. getAll() {
  80. return this.itemsBySlug;
  81. },
  82. getBySlug(slug) {
  83. return this.itemsBySlug[slug];
  84. },
  85. };
  86. const ProjectsStatsStore = createStore(storeConfig);
  87. export default ProjectsStatsStore;