chartContextMenu.tsx 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. import styled from '@emotion/styled';
  2. import Feature from 'sentry/components/acl/feature';
  3. import {DropdownMenu, type MenuItemProps} from 'sentry/components/dropdownMenu';
  4. import {IconEllipsis} from 'sentry/icons';
  5. import {t} from 'sentry/locale';
  6. import {trackAnalytics} from 'sentry/utils/analytics';
  7. import useOrganization from 'sentry/utils/useOrganization';
  8. import usePageFilters from 'sentry/utils/usePageFilters';
  9. import useProjects from 'sentry/utils/useProjects';
  10. import {Dataset} from 'sentry/views/alerts/rules/metric/types';
  11. import {useAddToDashboard} from 'sentry/views/explore/hooks/useAddToDashboard';
  12. import {getAlertsUrl} from 'sentry/views/insights/common/utils/getAlertsUrl';
  13. function ChartContextMenu({
  14. visualizeIndex,
  15. visualizeYAxes,
  16. query,
  17. interval,
  18. }: {
  19. interval: string;
  20. query: string;
  21. visualizeIndex: number;
  22. visualizeYAxes: string[];
  23. }) {
  24. const {addToDashboard} = useAddToDashboard();
  25. const organization = useOrganization();
  26. const {projects} = useProjects();
  27. const pageFilters = usePageFilters();
  28. const project =
  29. projects.length === 1
  30. ? projects[0]
  31. : projects.find(p => p.id === `${pageFilters.selection.projects[0]}`);
  32. const alertsUrls = visualizeYAxes.map((yAxis, index) => ({
  33. key: `${yAxis}-${index}`,
  34. label: yAxis,
  35. to: getAlertsUrl({
  36. project,
  37. query,
  38. pageFilters: pageFilters.selection,
  39. aggregate: yAxis,
  40. orgSlug: organization.slug,
  41. dataset: Dataset.EVENTS_ANALYTICS_PLATFORM,
  42. interval,
  43. }),
  44. onAction: () => {
  45. trackAnalytics('trace_explorer.save_as', {
  46. save_type: 'alert',
  47. ui_source: 'chart',
  48. organization,
  49. });
  50. return undefined;
  51. },
  52. }));
  53. const items: MenuItemProps[] = [];
  54. if (organization.features.includes('alerts-eap')) {
  55. items.push({
  56. key: 'create-alert',
  57. label: t('Create an alert for'),
  58. children: alertsUrls ?? [],
  59. disabled: !alertsUrls || alertsUrls.length === 0,
  60. isSubmenu: true,
  61. });
  62. }
  63. if (organization.features.includes('dashboards-eap')) {
  64. const disableAddToDashboard = !organization.features.includes('dashboards-edit');
  65. items.push({
  66. key: 'add-to-dashboard',
  67. textValue: t('Add to Dashboard'),
  68. label: (
  69. <Feature
  70. hookName="feature-disabled:dashboards-edit"
  71. features="organizations:dashboards-edit"
  72. renderDisabled={() => <DisabledText>{t('Add to Dashboard')}</DisabledText>}
  73. >
  74. {t('Add to Dashboard')}
  75. </Feature>
  76. ),
  77. disabled: disableAddToDashboard,
  78. onAction: () => {
  79. if (disableAddToDashboard) {
  80. return undefined;
  81. }
  82. trackAnalytics('trace_explorer.save_as', {
  83. save_type: 'dashboard',
  84. ui_source: 'chart',
  85. organization,
  86. });
  87. return addToDashboard(visualizeIndex);
  88. },
  89. });
  90. }
  91. if (items.length === 0) {
  92. return null;
  93. }
  94. return (
  95. <DropdownMenu
  96. triggerProps={{
  97. size: 'sm',
  98. borderless: true,
  99. showChevron: false,
  100. icon: <IconEllipsis />,
  101. }}
  102. position="bottom-end"
  103. items={items}
  104. />
  105. );
  106. }
  107. export default ChartContextMenu;
  108. const DisabledText = styled('span')`
  109. color: ${p => p.theme.disabled};
  110. `;