Files
2024-02-15 17:01:50 +00:00

219 lines
5.3 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import ExternalLink from 'sentry/components/links/externalLink';
import {DEFAULT_QUERY} from 'sentry/constants';
import {t, tct} from 'sentry/locale';
import type {Organization} from 'sentry/types';
export enum Query {
FOR_REVIEW = 'is:unresolved is:for_review assigned_or_suggested:[me, my_teams, none]',
UNRESOLVED = 'is:unresolved',
IGNORED = 'is:ignored',
NEW = 'is:new',
ARCHIVED = 'is:archived',
ESCALATING = 'is:escalating',
REGRESSED = 'is:regressed',
REPROCESSING = 'is:reprocessing',
}
export const CUSTOM_TAB_VALUE = '__custom__';
type OverviewTab = {
/**
* Emitted analytics event tab name
*/
analyticsName: string;
/**
* Will fetch a count to display on this tab
*/
count: boolean;
/**
* Tabs can be disabled via flag
*/
enabled: boolean;
name: string;
hidden?: boolean;
/**
* Tooltip text to be hoverable when text has links
*/
tooltipHoverable?: boolean;
/**
* Tooltip text for each tab
*/
tooltipTitle?: React.ReactNode;
};
/**
* Get a list of currently active tabs
*/
export function getTabs(organization: Organization) {
const tabs: Array<[string, OverviewTab]> = [
[
Query.UNRESOLVED,
{
name: t('Unresolved'),
analyticsName: 'unresolved',
count: true,
enabled: true,
},
],
[
Query.FOR_REVIEW,
{
name: t('For Review'),
analyticsName: 'needs_review',
count: true,
enabled: true,
tooltipTitle: t(
'Issues are marked for review if they are new or escalating, and have not been resolved or archived. Issues are automatically marked reviewed in 7 days.'
),
},
],
[
Query.REGRESSED,
{
name: t('Regressed'),
analyticsName: 'regressed',
count: true,
enabled: true,
},
],
[
Query.ESCALATING,
{
name: t('Escalating'),
analyticsName: 'escalating',
count: true,
enabled: true,
},
],
[
Query.ARCHIVED,
{
name: t('Archived'),
analyticsName: 'archived',
count: true,
enabled: true,
},
],
[
Query.IGNORED,
{
name: t('Ignored'),
analyticsName: 'ignored',
count: true,
enabled: false,
tooltipTitle: t(`Ignored issues don’t trigger alerts. When their ignore
conditions are met they become Unresolved and are flagged for review.`),
},
],
[
Query.REPROCESSING,
{
name: t('Reprocessing'),
analyticsName: 'reprocessing',
count: true,
enabled: organization.features.includes('reprocessing-v2'),
tooltipTitle: tct(
`These [link:reprocessing issues] will take some time to complete.
Any new issues that are created during reprocessing will be flagged for review.`,
{
link: (
<ExternalLink href="https://docs.sentry.io/product/error-monitoring/reprocessing/" />
),
}
),
tooltipHoverable: true,
},
],
[
// Hidden tab to account for custom queries that don't match any of the queries
// above. It's necessary because if Tabs's value doesn't match that of any tab item
// then Tabs will fall back to a default value, causing unexpected behaviors.
CUSTOM_TAB_VALUE,
{
name: t('Custom'),
analyticsName: 'custom',
hidden: true,
count: false,
enabled: true,
},
],
];
return tabs.filter(([_query, tab]) => tab.enabled);
}
/**
* @returns queries that should have counts fetched
*/
export function getTabsWithCounts(organization: Organization) {
const tabs = getTabs(organization);
return tabs.filter(([_query, tab]) => tab.count).map(([query]) => query);
}
export function isForReviewQuery(query: string | undefined) {
return !!query && /\bis:for_review\b/.test(query);
}
// the tab counts will look like 99+
export const TAB_MAX_COUNT = 99;
type QueryCount = {
count: number;
hasMore: boolean;
};
export type QueryCounts = Partial<Record<Query, QueryCount>>;
export enum IssueSortOptions {
DATE = 'date',
NEW = 'new',
PRIORITY = 'priority',
FREQ = 'freq',
USER = 'user',
INBOX = 'inbox',
}
export const DEFAULT_ISSUE_STREAM_SORT = IssueSortOptions.DATE;
export function isDefaultIssueStreamSearch({query, sort}: {query: string; sort: string}) {
return query === DEFAULT_QUERY && sort === DEFAULT_ISSUE_STREAM_SORT;
}
export function getSortLabel(key: string) {
switch (key) {
case IssueSortOptions.NEW:
return t('First Seen');
case IssueSortOptions.PRIORITY:
return t('Priority');
case IssueSortOptions.FREQ:
return t('Events');
case IssueSortOptions.USER:
return t('Users');
case IssueSortOptions.INBOX:
return t('Date Added');
case IssueSortOptions.DATE:
default:
return t('Last Seen');
}
}
export const DISCOVER_EXCLUSION_FIELDS: string[] = [
'query',
'status',
'bookmarked_by',
'assigned',
'assigned_to',
'unassigned',
'subscribed_by',
'active_at',
'first_release',
'first_seen',
'is',
'__text',
];
export const FOR_REVIEW_QUERIES: string[] = [Query.FOR_REVIEW];
export const SAVED_SEARCHES_SIDEBAR_OPEN_LOCALSTORAGE_KEY =
'issue-stream-saved-searches-sidebar-open';