starfishProjectSelector.tsx 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. import {updateProjects} from 'sentry/actionCreators/pageFilters';
  2. import {CompactSelect} from 'sentry/components/compactSelect';
  3. import ProjectBadge from 'sentry/components/idBadge/projectBadge';
  4. import {t} from 'sentry/locale';
  5. import {Project} from 'sentry/types';
  6. import useOrganization from 'sentry/utils/useOrganization';
  7. import usePageFilters from 'sentry/utils/usePageFilters';
  8. import useProjects from 'sentry/utils/useProjects';
  9. import useRouter from 'sentry/utils/useRouter';
  10. import {ALLOWED_PROJECT_IDS_FOR_ORG_SLUG} from 'sentry/views/starfish/allowedProjects';
  11. export function StarfishProjectSelector() {
  12. const {projects, initiallyLoaded: projectsLoaded, fetchError} = useProjects();
  13. const organization = useOrganization();
  14. const {selection, isReady} = usePageFilters();
  15. const router = useRouter();
  16. if (!projectsLoaded || !isReady) {
  17. return (
  18. <CompactSelect
  19. disabled
  20. options={[{label: t('Loading\u2026'), value: 'loading'}]}
  21. defaultValue="loading"
  22. />
  23. );
  24. }
  25. if (fetchError) {
  26. throw new Error('Failed to fetch projects');
  27. }
  28. const allowedProjectIDs: string[] =
  29. ALLOWED_PROJECT_IDS_FOR_ORG_SLUG[organization.slug] ?? [];
  30. const projectOptions = projects
  31. .filter(project => allowedProjectIDs.includes(project.id))
  32. .map(project => ({
  33. label: <ProjectOptionLabel project={project} />,
  34. value: project.id,
  35. }));
  36. const selectedOption =
  37. projectOptions.find(option =>
  38. selection.projects.includes(parseInt(option.value, 10))
  39. ) ?? projectOptions[0];
  40. const handleProjectChange = option =>
  41. updateProjects([parseInt(option.value, 10)], router, {save: true});
  42. if (
  43. selection.projects.length > 1 ||
  44. !allowedProjectIDs.includes(`${selection.projects[0]}`)
  45. ) {
  46. handleProjectChange(projectOptions[0]);
  47. }
  48. return (
  49. <CompactSelect
  50. menuWidth={250}
  51. options={projectOptions}
  52. defaultValue={selectedOption?.value}
  53. onChange={handleProjectChange}
  54. />
  55. );
  56. }
  57. function ProjectOptionLabel({project}: {project: Project}) {
  58. return <ProjectBadge project={project} avatarSize={20} disableLink />;
  59. }