import {useCallback, useMemo} from 'react'; import styled from '@emotion/styled'; import * as Sentry from '@sentry/react'; import {navigateTo} from 'sentry/actionCreators/navigation'; import Feature from 'sentry/components/acl/feature'; import {Button} from 'sentry/components/button'; import ButtonBar from 'sentry/components/buttonBar'; import {DropdownMenu} from 'sentry/components/dropdownMenu'; import { IconAdd, IconBookmark, IconDashboard, IconEllipsis, IconSettings, IconSiren, } from 'sentry/icons'; import {t} from 'sentry/locale'; import {trackAnalytics} from 'sentry/utils/analytics'; import {isCustomMeasurement} from 'sentry/utils/metrics'; import {MRIToField} from 'sentry/utils/metrics/mri'; import {middleEllipsis} from 'sentry/utils/middleEllipsis'; import useOrganization from 'sentry/utils/useOrganization'; import usePageFilters from 'sentry/utils/usePageFilters'; import useRouter from 'sentry/utils/useRouter'; import {useDDMContext} from 'sentry/views/ddm/context'; import {getCreateAlert} from 'sentry/views/ddm/contextMenu'; import {QuerySymbol} from 'sentry/views/ddm/querySymbol'; import {useCreateDashboard} from 'sentry/views/ddm/useCreateDashboard'; interface Props { addCustomMetric: () => void; showCustomMetricButton: boolean; } export function PageHeaderActions({showCustomMetricButton, addCustomMetric}: Props) { const router = useRouter(); const organization = useOrganization(); const {selection} = usePageFilters(); const createDashboard = useCreateDashboard(); const { addWidget, isDefaultQuery, setDefaultQuery, widgets, showQuerySymbols, selectedWidgetIndex, } = useDDMContext(); const hasEmptyWidget = widgets.length === 0 || widgets.some(widget => !widget.mri); const handleToggleDefaultQuery = useCallback(() => { if (isDefaultQuery) { Sentry.metrics.increment('ddm.remove-default-query'); trackAnalytics('ddm.remove-default-query', { organization, }); setDefaultQuery(null); } else { Sentry.metrics.increment('ddm.set-default-query'); trackAnalytics('ddm.set-default-query', { organization, }); setDefaultQuery(router.location.query); } }, [isDefaultQuery, organization, router.location.query, setDefaultQuery]); const items = useMemo( () => [ { leadingItems: [], key: 'add-query', label: t('Add Query'), disabled: hasEmptyWidget, onAction: () => { trackAnalytics('ddm.widget.add', { organization, }); Sentry.metrics.increment('ddm.widget.add'); addWidget(); }, }, { leadingItems: [], key: 'add-dashboard', label: ( {({hasFeature}) => ( {t('Add to Dashboard')} )} ), onAction: () => { if (!organization.features.includes('dashboards-edit')) { return; } trackAnalytics('ddm.add-to-dashboard', { organization, source: 'global', }); createDashboard(); }, }, { leadingItems: [], key: 'metrics-settings', label: t('Metrics Settings'), onAction: () => navigateTo(`/settings/projects/:projectId/metrics/`, router), }, ], [addWidget, createDashboard, hasEmptyWidget, organization, router] ); const alertItems = useMemo( () => widgets.map((widget, index) => { const createAlert = getCreateAlert(organization, { datetime: selection.datetime, projects: selection.projects, environments: selection.environments, query: widget.query, mri: widget.mri, groupBy: widget.groupBy, op: widget.op, }); return { leadingItems: showQuerySymbols ? [ , ] : [], key: `add-alert-${index}`, label: widget.mri ? middleEllipsis(MRIToField(widget.mri, widget.op!), 60, /\.|-|_/) : t('Select a metric to create an alert'), tooltip: isCustomMeasurement({mri: widget.mri}) ? t('Custom measurements cannot be used to create alerts') : undefined, disabled: !createAlert, onAction: () => { trackAnalytics('ddm.create-alert', { organization, source: 'global', }); createAlert?.(); }, }; }), [ organization, selectedWidgetIndex, selection.datetime, selection.environments, selection.projects, showQuerySymbols, widgets, ] ); return ( {showCustomMetricButton && ( )} {alertItems.length === 1 ? ( ) : ( , }} position="bottom-end" /> )} , }} position="bottom-end" /> ); } const AddToDashboardItem = styled('div')<{disabled: boolean}>` color: ${p => (p.disabled ? p.theme.disabled : p.theme.textColor)}; `;