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 {
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 {MetricExpressionType, type MetricsQueryWidget} from 'sentry/utils/metrics/types';
import {middleEllipsis} from 'sentry/utils/middleEllipsis';
import useOrganization from 'sentry/utils/useOrganization';
import useRouter from 'sentry/utils/useRouter';
import {useMetricsContext} from 'sentry/views/metrics/context';
import {getCreateAlert} from 'sentry/views/metrics/metricQueryContextMenu';
import {QuerySymbol} from 'sentry/views/metrics/querySymbol';
import {useCreateDashboard} from 'sentry/views/metrics/useCreateDashboard';
import {useFormulaDependencies} from 'sentry/views/metrics/utils/useFormulaDependencies';
interface Props {
addCustomMetric: () => void;
showCustomMetricButton: boolean;
}
export function PageHeaderActions({showCustomMetricButton, addCustomMetric}: Props) {
const router = useRouter();
const organization = useOrganization();
const formulaDependencies = useFormulaDependencies();
const {
isDefaultQuery,
setDefaultQuery,
widgets,
showQuerySymbols,
selectedWidgetIndex,
isMultiChartMode,
} = useMetricsContext();
const createDashboard = useCreateDashboard(
widgets,
formulaDependencies,
isMultiChartMode
);
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-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),
},
],
[createDashboard, organization, router]
);
const alertItems = useMemo(
() =>
widgets
.filter(
(query): query is MetricsQueryWidget =>
query.type === MetricExpressionType.QUERY
)
.map((widget, index) => {
const createAlert = getCreateAlert(organization, {
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?.();
},
};
}),
[isMultiChartMode, organization, selectedWidgetIndex, showQuerySymbols, widgets]
);
return (
{showCustomMetricButton && (
)}
}
onClick={handleToggleDefaultQuery}
>
{isDefaultQuery ? t('Remove Default') : t('Save as default')}
{alertItems.length === 1 ? (
}
disabled={!alertItems[0].onAction}
onClick={alertItems[0].onAction}
>
{t('Create Alert')}
) : (
,
}}
position="bottom-end"
/>
)}
,
}}
position="bottom-end"
/>
);
}
const AddToDashboardItem = styled('div')<{disabled: boolean}>`
color: ${p => (p.disabled ? p.theme.disabled : p.theme.textColor)};
`;