useCurrentProjectState.tsx 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. import {useEffect, useMemo, useState} from 'react';
  2. import partition from 'lodash/partition';
  3. import {
  4. customMetricOnboardingPlatforms,
  5. customMetricPlatforms,
  6. } from 'sentry/data/platformCategories';
  7. import PageFiltersStore from 'sentry/stores/pageFiltersStore';
  8. import {useLegacyStore} from 'sentry/stores/useLegacyStore';
  9. import type {Project} from 'sentry/types';
  10. import useProjects from 'sentry/utils/useProjects';
  11. export function useCurrentProjectState({isActive}: {isActive: boolean}) {
  12. const [currentProject, setCurrentProject] = useState<Project | undefined>(undefined);
  13. const {projects, initiallyLoaded: projectsLoaded} = useProjects();
  14. const {selection, isReady} = useLegacyStore(PageFiltersStore);
  15. const [supportedProjects, unsupportedProjects] = useMemo(() => {
  16. return partition(projects, p => p.platform && customMetricPlatforms.has(p.platform));
  17. }, [projects]);
  18. // Projects where we have the onboarding instructions ready:
  19. const projectsWithOnboarding = useMemo(
  20. () =>
  21. supportedProjects.filter(
  22. p => p.platform && customMetricOnboardingPlatforms.has(p.platform)
  23. ),
  24. [supportedProjects]
  25. );
  26. useEffect(() => {
  27. if (!isActive) {
  28. setCurrentProject(undefined);
  29. }
  30. }, [isActive]);
  31. useEffect(() => {
  32. if (currentProject || !projectsLoaded || !projects.length || !isReady || !isActive) {
  33. return;
  34. }
  35. if (!supportedProjects) {
  36. return;
  37. }
  38. if (selection.projects.length) {
  39. const selectedProjectIds = selection.projects.map(String);
  40. // If we selected something that has onboarding instructions, pick that first
  41. const projectWithOnboarding = projectsWithOnboarding.find(p =>
  42. selectedProjectIds.includes(p.id)
  43. );
  44. if (projectWithOnboarding) {
  45. setCurrentProject(projectWithOnboarding);
  46. return;
  47. }
  48. // If we selected something that supports custom metrics pick that
  49. const projectSupportsMetrics = supportedProjects.find(p =>
  50. selectedProjectIds.includes(p.id)
  51. );
  52. if (projectSupportsMetrics) {
  53. setCurrentProject(projectSupportsMetrics);
  54. return;
  55. }
  56. // Else pick the first selected project
  57. const firstSelectedProject = projects.find(p => selectedProjectIds.includes(p.id));
  58. setCurrentProject(firstSelectedProject);
  59. } else {
  60. setCurrentProject(projectsWithOnboarding.at(0) || supportedProjects.at(0));
  61. }
  62. }, [
  63. currentProject,
  64. projectsLoaded,
  65. projects,
  66. isReady,
  67. isActive,
  68. selection.projects,
  69. projectsWithOnboarding,
  70. supportedProjects,
  71. ]);
  72. return {
  73. projects: supportedProjects,
  74. hasDocs:
  75. !!currentProject?.platform &&
  76. customMetricOnboardingPlatforms.has(currentProject.platform),
  77. allProjects: projects,
  78. supportedProjects,
  79. unsupportedProjects,
  80. currentProject,
  81. setCurrentProject,
  82. };
  83. }