useCurrentProjectState.tsx 2.9 KB

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