import {Fragment} from 'react'; import styled from '@emotion/styled'; import {Breadcrumbs, type Crumb} from 'sentry/components/breadcrumbs'; import ButtonBar from 'sentry/components/buttonBar'; import {Badge} from 'sentry/components/core/badge'; import FeedbackWidgetButton from 'sentry/components/feedback/widget/feedbackWidgetButton'; import * as Layout from 'sentry/components/layouts/thirds'; import {extractSelectionParameters} from 'sentry/components/organizations/pageFilters/utils'; import {TabList} from 'sentry/components/tabs'; import type {TabListItemProps} from 'sentry/components/tabs/item'; import {IconBusiness} from 'sentry/icons'; import {t} from 'sentry/locale'; import {space} from 'sentry/styles/space'; import {useLocation} from 'sentry/utils/useLocation'; import useOrganization from 'sentry/utils/useOrganization'; import {useModuleTitles} from 'sentry/views/insights/common/utils/useModuleTitle'; import { type RoutableModuleNames, useModuleURLBuilder, } from 'sentry/views/insights/common/utils/useModuleURL'; import {OVERVIEW_PAGE_TITLE} from 'sentry/views/insights/pages/settings'; import { isModuleConsideredNew, isModuleEnabled, isModuleVisible, } from 'sentry/views/insights/pages/utils'; import type {ModuleName} from 'sentry/views/insights/types'; export type Props = { domainBaseUrl: string; domainTitle: string; modules: ModuleName[]; selectedModule: ModuleName | undefined; additionalBreadCrumbs?: Crumb[]; additonalHeaderActions?: React.ReactNode; // TODO - hasOverviewPage could be improved, the overview page could just be a "module", but that has a lot of other implications that have to be considered hasOverviewPage?: boolean; headerTitle?: React.ReactNode; hideDefaultTabs?: boolean; tabs?: {onTabChange: (key: string) => void; tabList: React.ReactNode; value: string}; }; export function DomainViewHeader({ modules, hasOverviewPage = true, headerTitle, domainTitle, selectedModule, hideDefaultTabs, additonalHeaderActions, additionalBreadCrumbs = [], domainBaseUrl, tabs, }: Props) { const organization = useOrganization(); const location = useLocation(); const moduleURLBuilder = useModuleURLBuilder(); const crumbs: Crumb[] = [ { label: domainTitle, to: domainBaseUrl, preservePageFilters: true, }, ...additionalBreadCrumbs, ]; const tabValue = hideDefaultTabs && tabs?.value ? tabs.value : (selectedModule ?? OVERVIEW_PAGE_TITLE); const globalQuery = extractSelectionParameters(location?.query); const tabList: TabListItemProps[] = [ ...(hasOverviewPage ? [ { key: OVERVIEW_PAGE_TITLE, children: OVERVIEW_PAGE_TITLE, to: {pathname: domainBaseUrl, query: globalQuery}, }, ] : []), ...modules .filter(moduleName => isModuleVisible(moduleName, organization)) .map(moduleName => ({ key: moduleName, children: , textValue: moduleName, to: { pathname: `${moduleURLBuilder(moduleName as RoutableModuleNames)}/`, query: globalQuery, }, })), ]; return ( {crumbs.length > 1 && } {headerTitle || domainTitle} {additonalHeaderActions} {!hideDefaultTabs && ( {tabList.map(tab => ( ))} )} {hideDefaultTabs && tabs && tabs.tabList} ); } interface TabLabelProps { moduleName: ModuleName; } function TabLabel({moduleName}: TabLabelProps) { const moduleTitles = useModuleTitles(); const organization = useOrganization(); const showBusinessIcon = !isModuleEnabled(moduleName, organization); if (showBusinessIcon || isModuleConsideredNew(moduleName)) { return ( {moduleTitles[moduleName]} {isModuleConsideredNew(moduleName) && {t('New')}} {showBusinessIcon && } ); } return moduleTitles[moduleName]; } const TabContainer = styled('div')` display: inline-flex; align-items: center; text-align: left; gap: ${space(0.5)}; `;