import {Fragment} from 'react';
import {Alert} from 'sentry/components/alert';
import ExternalLink from 'sentry/components/links/externalLink';
import {t, tct, tn} from 'sentry/locale';
import type {IgnoredStatusDetails} from 'sentry/types/group';
import {capitalize} from 'sentry/utils/string/capitalize';
import commonTheme from 'sentry/utils/theme';
import ExtraDescription from './extraDescription';
export const BULK_LIMIT = 1000;
export const BULK_LIMIT_STR = BULK_LIMIT.toLocaleString();
export enum ConfirmAction {
RESOLVE = 'resolve',
UNRESOLVE = 'unresolve',
ARCHIVE = 'archive',
BOOKMARK = 'bookmark',
UNBOOKMARK = 'unbookmark',
MERGE = 'merge',
DELETE = 'delete',
SET_PRIORITY = 'reprioritize',
}
function getBulkConfirmMessage(action: string, queryCount: number) {
if (queryCount > BULK_LIMIT) {
return tct(
'Are you sure you want to [action] the first [bulkNumber] issues that match the search?',
{
action,
bulkNumber: BULK_LIMIT_STR,
}
);
}
return tct(
'Are you sure you want to [action] all [bulkNumber] issues that match the search?',
{
action,
bulkNumber: queryCount,
}
);
}
function PerformanceIssueAlert({
allInQuerySelected,
children,
}: {
allInQuerySelected: boolean;
children: string;
}) {
if (!allInQuerySelected) {
return null;
}
return (
{children}
);
}
export function getConfirm({
numIssues,
allInQuerySelected,
query,
queryCount,
}: {
allInQuerySelected: boolean;
numIssues: number;
query: string;
queryCount: number;
}) {
return function ({
action,
canBeUndone,
append = '',
}: {
action: ConfirmAction;
canBeUndone: boolean;
append?: string;
}) {
const question = allInQuerySelected
? getBulkConfirmMessage(`${action}${append}`, queryCount)
: tn(
// Use sprintf argument swapping since the number value must come
// first. See https://github.com/alexei/sprintf.js#argument-swapping
`Are you sure you want to %2$s this %s issue%3$s?`,
`Are you sure you want to %2$s these %s issues%3$s?`,
numIssues,
action,
append
);
let message: React.ReactNode;
switch (action) {
case ConfirmAction.DELETE:
message = (
{tct(
'Bulk deletion is only recommended for junk data. To clear your stream, consider resolving or ignoring. [link:When should I delete events?]',
{
link: (
),
}
)}
{t('Deleting performance issues is not yet supported and will be skipped.')}
);
break;
case ConfirmAction.MERGE:
message = (
{t('Note that unmerging is currently an experimental feature.')}
{t('Merging performance issues is not yet supported and will be skipped.')}
);
break;
default:
message = !canBeUndone ?
{t('This action cannot be undone.')}
: null;
}
return (
);
};
}
export function getLabel(numIssues: number, allInQuerySelected: boolean) {
return function (action: string, append = '') {
const capitalized = capitalize(action);
const text = allInQuerySelected
? t('Bulk %s issues', action)
: // Use sprintf argument swapping to put the capitalized string first. See
// https://github.com/alexei/sprintf.js#argument-swapping
tn(`%2$s %s selected issue`, `%2$s %s selected issues`, numIssues, capitalized);
return text + append;
};
}
export function performanceIssuesSupportsIgnoreAction(
statusDetails: IgnoredStatusDetails
) {
return !(statusDetails.ignoreWindow || statusDetails.ignoreUserWindow);
}
// A mapping of which screen sizes will trigger the column to disappear
// e.g. 'Trend': screen.small => 'Trend' column will disappear on screen.small widths
export const COLUMN_BREAKPOINTS = {
ISSUE: undefined, // Issue column is always visible
TREND: commonTheme.breakpoints.small,
AGE: commonTheme.breakpoints.xlarge,
SEEN: commonTheme.breakpoints.xlarge,
EVENTS: commonTheme.breakpoints.medium,
USERS: commonTheme.breakpoints.medium,
PRIORITY: commonTheme.breakpoints.large,
ASSIGNEE: commonTheme.breakpoints.xsmall,
};