123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394 |
- import type {Location} from 'history';
- import omit from 'lodash/omit';
- import type {Crumb} from 'sentry/components/breadcrumbs';
- import {t} from 'sentry/locale';
- import type {Organization} from 'sentry/types/organization';
- import normalizeUrl from 'sentry/utils/url/normalizeUrl';
- import type {
- RoutableModuleNames,
- URLBuilder,
- } from 'sentry/views/insights/common/utils/useModuleURL';
- import {
- DOMAIN_VIEW_BASE_TITLE,
- DOMAIN_VIEW_BASE_URL,
- } from 'sentry/views/insights/pages/settings';
- import {DOMAIN_VIEW_TITLES} from 'sentry/views/insights/pages/types';
- import type {DomainView} from 'sentry/views/insights/pages/useFilters';
- import {MODULE_TITLES} from 'sentry/views/insights/settings';
- import {ModuleName} from 'sentry/views/insights/types';
- import {getTransactionSummaryBaseUrl} from 'sentry/views/performance/transactionSummary/utils';
- import {getPerformanceBaseUrl} from 'sentry/views/performance/utils';
- import Tab from '../../transactionSummary/tabs';
- export const enum TraceViewSources {
- TRACES = 'traces',
- METRICS = 'metrics',
- DISCOVER = 'discover',
- PROFILING_FLAMEGRAPH = 'profiling_flamegraph',
- REQUESTS_MODULE = 'requests_module',
- QUERIES_MODULE = 'queries_module',
- ASSETS_MODULE = 'assets_module',
- APP_STARTS_MODULE = 'app_starts_module',
- SCREEN_LOADS_MODULE = 'screen_loads_module',
- WEB_VITALS_MODULE = 'web_vitals_module',
- CACHES_MODULE = 'caches_module',
- QUEUES_MODULE = 'queues_module',
- LLM_MODULE = 'llm_module',
- SCREEN_LOAD_MODULE = 'screen_load_module',
- MOBILE_SCREENS_MODULE = 'mobile_screens_module',
- SCREEN_RENDERING_MODULE = 'screen_rendering_module',
- PERFORMANCE_TRANSACTION_SUMMARY = 'performance_transaction_summary',
- PERFORMANCE_TRANSACTION_SUMMARY_PROFILES = 'performance_transaction_summary_profiles',
- ISSUE_DETAILS = 'issue_details',
- FEEDBACK_DETAILS = 'feedback_details',
- }
- // Ideally every new entry to ModuleName, would require a new source to be added here so we don't miss any.
- const TRACE_SOURCE_TO_MODULE: Partial<Record<TraceViewSources, ModuleName>> = {
- app_starts_module: ModuleName.APP_START,
- assets_module: ModuleName.RESOURCE,
- caches_module: ModuleName.CACHE,
- llm_module: ModuleName.AI,
- queries_module: ModuleName.DB,
- requests_module: ModuleName.HTTP,
- screen_loads_module: ModuleName.SCREEN_LOAD,
- web_vitals_module: ModuleName.VITAL,
- queues_module: ModuleName.QUEUE,
- screen_load_module: ModuleName.SCREEN_LOAD,
- screen_rendering_module: ModuleName.SCREEN_RENDERING,
- mobile_screens_module: ModuleName.MOBILE_SCREENS,
- };
- function getBreadCrumbTarget(
- path: string,
- query: Location['query'],
- organization: Organization
- ) {
- return {
- pathname: normalizeUrl(`/organizations/${organization.slug}/${path}`),
- // Remove traceView specific query parameters that are not needed when navigating back.
- query: {...omit(query, ['node', 'fov', 'timestamp', 'eventId'])},
- };
- }
- function getPerformanceBreadCrumbs(
- organization: Organization,
- location: Location,
- view?: DomainView
- ) {
- const crumbs: Crumb[] = [];
- const performanceUrl = getPerformanceBaseUrl(organization.slug, view, true);
- const transactionSummaryUrl = getTransactionSummaryBaseUrl(
- organization.slug,
- view,
- true
- );
- if (view) {
- crumbs.push({
- label: DOMAIN_VIEW_BASE_TITLE,
- to: undefined,
- });
- }
- crumbs.push({
- label: (view && DOMAIN_VIEW_TITLES[view]) || t('Performance'),
- to: getBreadCrumbTarget(performanceUrl, location.query, organization),
- });
- switch (location.query.tab) {
- case Tab.EVENTS:
- crumbs.push({
- label: t('All Events'),
- to: getBreadCrumbTarget(
- `${transactionSummaryUrl}/events`,
- location.query,
- organization
- ),
- });
- break;
- case Tab.TAGS:
- crumbs.push({
- label: t('Tags'),
- to: getBreadCrumbTarget(
- `${transactionSummaryUrl}/tags`,
- location.query,
- organization
- ),
- });
- break;
- case Tab.SPANS:
- crumbs.push({
- label: t('Spans'),
- to: getBreadCrumbTarget(
- `${transactionSummaryUrl}/spans`,
- location.query,
- organization
- ),
- });
- const {spanSlug} = location.query;
- if (spanSlug) {
- crumbs.push({
- label: t('Span Summary'),
- to: getBreadCrumbTarget(
- `${transactionSummaryUrl}/spans/${spanSlug}`,
- location.query,
- organization
- ),
- });
- }
- break;
- case Tab.AGGREGATE_WATERFALL:
- crumbs.push({
- label: t('Transaction Summary'),
- to: getBreadCrumbTarget(
- `${transactionSummaryUrl}/aggregateWaterfall`,
- location.query,
- organization
- ),
- });
- break;
- default:
- crumbs.push({
- label: t('Transaction Summary'),
- to: getBreadCrumbTarget(`${transactionSummaryUrl}`, location.query, organization),
- });
- break;
- }
- crumbs.push({
- label: t('Trace View'),
- });
- return crumbs;
- }
- function getIssuesBreadCrumbs(organization: Organization, location: Location) {
- const crumbs: Crumb[] = [];
- crumbs.push({
- label: t('Issues'),
- to: getBreadCrumbTarget(`issues`, location.query, organization),
- });
- if (location.query.groupId) {
- crumbs.push({
- label: t('Issue Details'),
- to: getBreadCrumbTarget(
- `issues/${location.query.groupId}`,
- location.query,
- organization
- ),
- });
- }
- crumbs.push({
- label: t('Trace View'),
- });
- return crumbs;
- }
- function getInsightsModuleBreadcrumbs(
- location: Location,
- organization: Organization,
- moduleURLBuilder: URLBuilder,
- view?: DomainView
- ) {
- const crumbs: Crumb[] = [];
- if (view && DOMAIN_VIEW_TITLES[view]) {
- crumbs.push({
- label: DOMAIN_VIEW_BASE_TITLE,
- to: undefined,
- });
- crumbs.push({
- label: DOMAIN_VIEW_TITLES[view],
- to: getBreadCrumbTarget(
- `${DOMAIN_VIEW_BASE_URL}/${view}/`,
- location.query,
- organization
- ),
- });
- } else {
- crumbs.push({
- label: t('Insights'),
- });
- }
- let moduleName: RoutableModuleNames | undefined = undefined;
- if (
- typeof location.query.source === 'string' &&
- TRACE_SOURCE_TO_MODULE[location.query.source]
- ) {
- moduleName = TRACE_SOURCE_TO_MODULE[location.query.source] as RoutableModuleNames;
- crumbs.push({
- label: MODULE_TITLES[moduleName],
- to: moduleURLBuilder(moduleName),
- });
- }
- switch (moduleName) {
- case ModuleName.HTTP:
- crumbs.push({
- label: t('Domain Summary'),
- to: getBreadCrumbTarget(
- `${moduleURLBuilder(moduleName, view)}/domains`,
- location.query,
- organization
- ),
- });
- break;
- case ModuleName.DB:
- if (location.query.groupId) {
- crumbs.push({
- label: t('Query Summary'),
- to: getBreadCrumbTarget(
- `${moduleURLBuilder(moduleName, view)}/spans/span/${location.query.groupId}`,
- location.query,
- organization
- ),
- });
- } else {
- crumbs.push({
- label: t('Query Summary'),
- });
- }
- break;
- case ModuleName.RESOURCE:
- if (location.query.groupId) {
- crumbs.push({
- label: t('Asset Summary'),
- to: getBreadCrumbTarget(
- `${moduleURLBuilder(moduleName)}/spans/span/${location.query.groupId}`,
- location.query,
- organization
- ),
- });
- } else {
- crumbs.push({
- label: t('Asset Summary'),
- });
- }
- break;
- case ModuleName.APP_START:
- crumbs.push({
- label: t('Screen Summary'),
- to: getBreadCrumbTarget(
- `${moduleURLBuilder(moduleName, view)}/spans`,
- location.query,
- organization
- ),
- });
- break;
- case ModuleName.SCREEN_LOAD:
- crumbs.push({
- label: t('Screen Summary'),
- to: getBreadCrumbTarget(
- `${moduleURLBuilder(moduleName, view)}/spans`,
- location.query,
- organization
- ),
- });
- break;
- case ModuleName.VITAL:
- crumbs.push({
- label: t('Page Overview'),
- to: getBreadCrumbTarget(
- `${moduleURLBuilder(moduleName, view)}/overview`,
- location.query,
- organization
- ),
- });
- break;
- case ModuleName.QUEUE:
- crumbs.push({
- label: t('Destination Summary'),
- to: getBreadCrumbTarget(
- `${moduleURLBuilder(moduleName, view)}/destination`,
- location.query,
- organization
- ),
- });
- break;
- case ModuleName.AI:
- if (location.query.groupId) {
- crumbs.push({
- label: t('Pipeline Summary'),
- to: getBreadCrumbTarget(
- `${moduleURLBuilder(moduleName, view)}/pipeline-type/${location.query.groupId}`,
- location.query,
- organization
- ),
- });
- }
- break;
- case ModuleName.CACHE:
- default:
- break;
- }
- crumbs.push({
- label: t('Trace View'),
- });
- return crumbs;
- }
- export function getTraceViewBreadcrumbs(
- organization: Organization,
- location: Location,
- moduleUrlBuilder: URLBuilder,
- view?: DomainView
- ): Crumb[] {
- if (
- typeof location.query.source === 'string' &&
- TRACE_SOURCE_TO_MODULE[location.query.source]
- ) {
- return getInsightsModuleBreadcrumbs(location, organization, moduleUrlBuilder, view);
- }
- switch (location.query.source) {
- case TraceViewSources.TRACES:
- return [
- {
- label: t('Traces'),
- to: getBreadCrumbTarget(`traces`, location.query, organization),
- },
- {
- label: t('Trace View'),
- },
- ];
- case TraceViewSources.DISCOVER:
- return [
- {
- label: t('Discover'),
- to: getBreadCrumbTarget(`discover/homepage`, location.query, organization),
- },
- {
- label: t('Trace View'),
- },
- ];
- case TraceViewSources.METRICS:
- return [
- {
- label: t('Metrics'),
- to: getBreadCrumbTarget(`metrics`, location.query, organization),
- },
- {
- label: t('Trace View'),
- },
- ];
- case TraceViewSources.ISSUE_DETAILS:
- return getIssuesBreadCrumbs(organization, location);
- case TraceViewSources.PERFORMANCE_TRANSACTION_SUMMARY:
- return getPerformanceBreadCrumbs(organization, location, view);
- default:
- return [{label: t('Trace View')}];
- }
- }
|