Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(insights): ensure all links within domain views, stay within domain views #77804

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion static/app/components/sidebar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ function Sidebar() {
</Feature>
);

const moduleURLBuilder = useModuleURLBuilder(true);
const moduleURLBuilder = useModuleURLBuilder(true, false);

const queries = hasOrganization && (
<Feature key="db" features="insights-entry-points" organization={organization}>
Expand Down
8 changes: 4 additions & 4 deletions static/app/routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1642,19 +1642,19 @@ function buildRoutes() {
component={make(() => import('sentry/views/performance/trends'))}
/>
<Route
path={`${FRONTEND_LANDING_SUB_PATH}/`}
path={`${FRONTEND_LANDING_SUB_PATH}/*`}
component={make(() => import('sentry/views/insights/pages/frontendLandingPage'))}
/>
<Route
path={`${BACKEND_LANDING_SUB_PATH}/`}
path={`${BACKEND_LANDING_SUB_PATH}/*`}
component={make(() => import('sentry/views/insights/pages/backendLandingPage'))}
/>
<Route
path={`${MOBILE_LANDING_SUB_PATH}/`}
path={`${MOBILE_LANDING_SUB_PATH}/*`}
component={make(() => import('sentry/views/insights/pages/mobileLandingPage'))}
/>
<Route
path={`${AI_LANDING_SUB_PATH}/`}
path={`${AI_LANDING_SUB_PATH}/*`}
component={make(() => import('sentry/views/insights/pages/aiLandingPage'))}
/>
<Route path="summary/">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import {useModuleBreadcrumbs} from 'sentry/views/insights/common/utils/useModule
import {useModuleURL} from 'sentry/views/insights/common/utils/useModuleURL';
import SubregionSelector from 'sentry/views/insights/common/views/spans/selectors/subregionSelector';
import {SampleList} from 'sentry/views/insights/common/views/spanSummaryPage/sampleList';
import {useFilters} from 'sentry/views/insights/pages/useFilters';
import {ModuleName, SpanMetricsField} from 'sentry/views/insights/types';
import {TraceViewSources} from 'sentry/views/performance/newTraceDetails/traceMetadataHeader';

Expand All @@ -46,7 +47,13 @@ const {

function ResourceSummary() {
const webVitalsModuleURL = useModuleURL('vital');
const {groupId} = useParams();
const location = useLocation();
const {isInDomainView} = useFilters();
let {groupId} = useParams();
if (isInDomainView) {
groupId = location.pathname.split('/').filter(Boolean).pop() || '';
}

const filters = useResourceModuleFilters();
const selectedSpanOp = filters[SPAN_OP];
const {
Expand Down
18 changes: 15 additions & 3 deletions static/app/views/insights/common/utils/useModuleURL.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {BASE_URL as APP_STARTS_BASE_URL} from 'sentry/views/insights/mobile/appS
import {BASE_URL as SCREEN_LOADS_BASE_URL} from 'sentry/views/insights/mobile/screenload/settings';
import {BASE_URL as MOBILE_SCREENS_BASE_URL} from 'sentry/views/insights/mobile/screens/settings';
import {BASE_URL as MOBILE_UI_BASE_URL} from 'sentry/views/insights/mobile/ui/settings';
import {useFilters} from 'sentry/views/insights/pages/useFilters';
import {BASE_URL as QUEUE_BASE_URL} from 'sentry/views/insights/queues/settings';
import {INSIGHTS_BASE_URL} from 'sentry/views/insights/settings';
import {ModuleName} from 'sentry/views/insights/types';
Expand All @@ -34,16 +35,21 @@ type RoutableModuleNames = Exclude<ModuleNameStrings, '' | 'other'>;

export const useModuleURL = (
moduleName: RoutableModuleNames,
bare: boolean = false
bare: boolean = false,
detectDomainView: boolean = true
): string => {
const builder = useModuleURLBuilder(bare);
const builder = useModuleURLBuilder(bare, detectDomainView);
return builder(moduleName);
};

type URLBuilder = (moduleName: RoutableModuleNames) => string;

export function useModuleURLBuilder(bare: boolean = false): URLBuilder {
export function useModuleURLBuilder(
bare: boolean = false,
detectDomainView: boolean = true // we can delete this once domain views are released. This is needed to go from the insight links in the sidebar, when the user is already in a domain view
): URLBuilder {
const organization = useOrganization({allowNull: true}); // Some parts of the app, like the main sidebar, render even if the organization isn't available (during loading, or at all).
const {view, isInDomainView} = useFilters();

if (!organization) {
// If there isn't an organization, items that link to modules won't be visible, so this is a fallback just-in-case, and isn't trying too hard to be useful
Expand All @@ -52,6 +58,12 @@ export function useModuleURLBuilder(bare: boolean = false): URLBuilder {

const {slug} = organization;

if (isInDomainView && detectDomainView) {
return function (moduleName: RoutableModuleNames) {
return normalizeUrl(`/organizations/${slug}/performance/${view}/${moduleName}`);
};
}

return function (moduleName: RoutableModuleNames) {
return bare
? `${INSIGHTS_BASE_URL}/${MODULE_BASE_URLS[moduleName]}`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ interface Props {
pageLinks?: string;
};
sort: ValidSort;
disableHeader?: boolean;
}

export function DomainsTable({response, sort}: Props) {
Expand Down
6 changes: 5 additions & 1 deletion static/app/views/insights/http/views/httpLandingPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,11 @@ export function HTTPLandingPage({disableHeader}: InsightLandingProps) {
</ModuleLayout.Full>

<ModuleLayout.Full>
<DomainsTable response={domainsListResponse} sort={sort} />
<DomainsTable
response={domainsListResponse}
sort={sort}
disableHeader={disableHeader}
/>
</ModuleLayout.Full>
</ModulesOnboarding>
</ModuleLayout.Layout>
Expand Down
16 changes: 5 additions & 11 deletions static/app/views/insights/pages/aiLandingPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,23 @@ import {Breadcrumbs, type Crumb} from 'sentry/components/breadcrumbs';
import ButtonBar from 'sentry/components/buttonBar';
import FeedbackWidgetButton from 'sentry/components/feedback/widget/feedbackWidgetButton';
import * as Layout from 'sentry/components/layouts/thirds';
import {TabList, TabPanels, Tabs} from 'sentry/components/tabs';
import {TabList, Tabs} from 'sentry/components/tabs';
import {t} from 'sentry/locale';
import {PageAlert} from 'sentry/utils/performance/contexts/pageAlert';
import LLMLandingPage from 'sentry/views/insights/llmMonitoring/views/llmMonitoringLandingPage';
import {ModuleRenderer} from 'sentry/views/insights/pages/moduleRenderer';
import {OVERVIEW_PAGE_TITLE} from 'sentry/views/insights/pages/settings';
import {
type Filters,
useFilters,
useUpdateFilters,
} from 'sentry/views/insights/pages/useFilters';
import {MODULE_TITLES} from 'sentry/views/insights/settings';
import {type InsightLandingProps, ModuleName} from 'sentry/views/insights/types';
import {ModuleName} from 'sentry/views/insights/types';

function AiLandingPage() {
const filters = useFilters();
const updateFilters = useUpdateFilters();

const landingPageProps: InsightLandingProps = {disableHeader: true};

const crumbs: Crumb[] = [
{
label: t('Performance'),
Expand Down Expand Up @@ -78,12 +76,8 @@ function AiLandingPage() {
</Layout.Header>
<Layout.Main fullWidth>
<PageAlert />
<TabPanels>
<TabPanels.Item key={OVERVIEW_PAGE_TITLE}>{'overview page'}</TabPanels.Item>
<TabPanels.Item key={ModuleName.AI}>
<LLMLandingPage {...landingPageProps} />
</TabPanels.Item>
</TabPanels>
{!filters.module && 'overview page'}
{filters.module && <ModuleRenderer />}
</Layout.Main>
</Tabs>
</Fragment>
Expand Down
28 changes: 5 additions & 23 deletions static/app/views/insights/pages/backendLandingPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,23 @@
import ButtonBar from 'sentry/components/buttonBar';
import FeedbackWidgetButton from 'sentry/components/feedback/widget/feedbackWidgetButton';
import * as Layout from 'sentry/components/layouts/thirds';
import {TabList, TabPanels, Tabs} from 'sentry/components/tabs';
import {TabList, Tabs} from 'sentry/components/tabs';
import {t} from 'sentry/locale';
import {PageAlert} from 'sentry/utils/performance/contexts/pageAlert';
import CachesLandingPage from 'sentry/views/insights/cache/views/cacheLandingPage';
import DatabaseLandingPage from 'sentry/views/insights/database/views//databaseLandingPage';
import HTTPLandingPage from 'sentry/views/insights/http/views/httpLandingPage';
import {ModuleRenderer} from 'sentry/views/insights/pages/moduleRenderer';
import {OVERVIEW_PAGE_TITLE} from 'sentry/views/insights/pages/settings';
import {
type Filters,
useFilters,
useUpdateFilters,
} from 'sentry/views/insights/pages/useFilters';
import QueuesLandingPage from 'sentry/views/insights/queues/views/queuesLandingPage';
import {MODULE_TITLES} from 'sentry/views/insights/settings';
import {type InsightLandingProps, ModuleName} from 'sentry/views/insights/types';
import type {ModuleName} from 'sentry/views/insights/types';

function BackendLandingPage() {
const filters = useFilters();
const updateFilters = useUpdateFilters();

const landingPageProps: InsightLandingProps = {disableHeader: true};

const crumbs: Crumb[] = [
{
label: t('Performance'),
Expand Down Expand Up @@ -74,37 +69,24 @@
</Layout.HeaderActions>
<TabList>
<TabList.Item key={OVERVIEW_PAGE_TITLE}>{OVERVIEW_PAGE_TITLE}</TabList.Item>
<TabList.Item key={ModuleName.DB}>

Check failure on line 72 in static/app/views/insights/pages/backendLandingPage.tsx

View workflow job for this annotation

GitHub Actions / self-hosted

'ModuleName' cannot be used as a value because it was imported using 'import type'.
{MODULE_TITLES[ModuleName.DB]}

Check failure on line 73 in static/app/views/insights/pages/backendLandingPage.tsx

View workflow job for this annotation

GitHub Actions / self-hosted

'ModuleName' cannot be used as a value because it was imported using 'import type'.
</TabList.Item>
<TabList.Item key={ModuleName.HTTP}>

Check failure on line 75 in static/app/views/insights/pages/backendLandingPage.tsx

View workflow job for this annotation

GitHub Actions / self-hosted

'ModuleName' cannot be used as a value because it was imported using 'import type'.
{MODULE_TITLES[ModuleName.HTTP]}

Check failure on line 76 in static/app/views/insights/pages/backendLandingPage.tsx

View workflow job for this annotation

GitHub Actions / self-hosted

'ModuleName' cannot be used as a value because it was imported using 'import type'.
</TabList.Item>
<TabList.Item key={ModuleName.CACHE}>

Check failure on line 78 in static/app/views/insights/pages/backendLandingPage.tsx

View workflow job for this annotation

GitHub Actions / self-hosted

'ModuleName' cannot be used as a value because it was imported using 'import type'.
{MODULE_TITLES[ModuleName.CACHE]}

Check failure on line 79 in static/app/views/insights/pages/backendLandingPage.tsx

View workflow job for this annotation

GitHub Actions / self-hosted

'ModuleName' cannot be used as a value because it was imported using 'import type'.
</TabList.Item>
<TabList.Item key={ModuleName.QUEUE}>

Check failure on line 81 in static/app/views/insights/pages/backendLandingPage.tsx

View workflow job for this annotation

GitHub Actions / self-hosted

'ModuleName' cannot be used as a value because it was imported using 'import type'.
{MODULE_TITLES[ModuleName.QUEUE]}

Check failure on line 82 in static/app/views/insights/pages/backendLandingPage.tsx

View workflow job for this annotation

GitHub Actions / self-hosted

'ModuleName' cannot be used as a value because it was imported using 'import type'.
</TabList.Item>
</TabList>
</Layout.Header>
<Layout.Main fullWidth>
<PageAlert />
<TabPanels>
<TabPanels.Item key={OVERVIEW_PAGE_TITLE}>{'overview page'}</TabPanels.Item>
<TabPanels.Item key={ModuleName.DB}>
<DatabaseLandingPage {...landingPageProps} />
</TabPanels.Item>
<TabPanels.Item key={ModuleName.HTTP}>
<HTTPLandingPage {...landingPageProps} />
</TabPanels.Item>
<TabPanels.Item key={ModuleName.CACHE}>
<CachesLandingPage {...landingPageProps} />
</TabPanels.Item>
<TabPanels.Item key={ModuleName.QUEUE}>
<QueuesLandingPage {...landingPageProps} />
</TabPanels.Item>
</TabPanels>
{!filters.module && 'overview page'}
{filters.module && <ModuleRenderer />}
</Layout.Main>
</Tabs>
</Fragment>
Expand Down
26 changes: 6 additions & 20 deletions static/app/views/insights/pages/frontendLandingPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,23 @@ import {Breadcrumbs, type Crumb} from 'sentry/components/breadcrumbs';
import ButtonBar from 'sentry/components/buttonBar';
import FeedbackWidgetButton from 'sentry/components/feedback/widget/feedbackWidgetButton';
import * as Layout from 'sentry/components/layouts/thirds';
import {TabList, TabPanels, Tabs} from 'sentry/components/tabs';
import {TabList, Tabs} from 'sentry/components/tabs';
import {t} from 'sentry/locale';
import {PageAlert} from 'sentry/utils/performance/contexts/pageAlert';
import ResourcesLandingPage from 'sentry/views/insights/browser/resources/views/resourcesLandingPage';
import WebVitalsLandingPage from 'sentry/views/insights/browser/webVitals/views/webVitalsLandingPage';
import HTTPLandingPage from 'sentry/views/insights/http/views/httpLandingPage';
import {ModuleRenderer} from 'sentry/views/insights/pages/moduleRenderer';
import {OVERVIEW_PAGE_TITLE} from 'sentry/views/insights/pages/settings';
import {
type Filters,
useFilters,
useUpdateFilters,
} from 'sentry/views/insights/pages/useFilters';
import {MODULE_TITLES} from 'sentry/views/insights/settings';
import {type InsightLandingProps, ModuleName} from 'sentry/views/insights/types';
import {ModuleName} from 'sentry/views/insights/types';

function FrontendLandingPage() {
const filters = useFilters();
const updateFilters = useUpdateFilters();

const landingPageProps: InsightLandingProps = {disableHeader: true};

const crumbs: Crumb[] = [
{
label: t('Performance'),
Expand Down Expand Up @@ -72,7 +68,7 @@ function FrontendLandingPage() {
</ButtonBar>
</Layout.HeaderActions>
<TabList>
<TabList.Item key={OVERVIEW_PAGE_TITLE}>{'Overview'}</TabList.Item>
<TabList.Item key={OVERVIEW_PAGE_TITLE}>{OVERVIEW_PAGE_TITLE}</TabList.Item>
<TabList.Item key={ModuleName.VITAL}>
{MODULE_TITLES[ModuleName.VITAL]}
</TabList.Item>
Expand All @@ -86,18 +82,8 @@ function FrontendLandingPage() {
</Layout.Header>
<Layout.Main fullWidth>
<PageAlert />
<TabPanels>
<TabPanels.Item key={OVERVIEW_PAGE_TITLE}>{'overview page'}</TabPanels.Item>
<TabPanels.Item key={ModuleName.HTTP}>
<HTTPLandingPage {...landingPageProps} />
</TabPanels.Item>
<TabPanels.Item key={ModuleName.RESOURCE}>
<ResourcesLandingPage {...landingPageProps} />
</TabPanels.Item>
<TabPanels.Item key={ModuleName.VITAL}>
<WebVitalsLandingPage {...landingPageProps} />
</TabPanels.Item>
</TabPanels>
{!filters.module && 'overview page'}
{filters.module && <ModuleRenderer />}
</Layout.Main>
</Tabs>
</Fragment>
Expand Down
16 changes: 5 additions & 11 deletions static/app/views/insights/pages/mobileLandingPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,23 @@ import {Breadcrumbs, type Crumb} from 'sentry/components/breadcrumbs';
import ButtonBar from 'sentry/components/buttonBar';
import FeedbackWidgetButton from 'sentry/components/feedback/widget/feedbackWidgetButton';
import * as Layout from 'sentry/components/layouts/thirds';
import {TabList, TabPanels, Tabs} from 'sentry/components/tabs';
import {TabList, Tabs} from 'sentry/components/tabs';
import {t} from 'sentry/locale';
import {PageAlert} from 'sentry/utils/performance/contexts/pageAlert';
import ScreensLandingPage from 'sentry/views/insights/mobile/screens/views/screensLandingPage';
import {ModuleRenderer} from 'sentry/views/insights/pages/moduleRenderer';
import {OVERVIEW_PAGE_TITLE} from 'sentry/views/insights/pages/settings';
import {
type Filters,
useFilters,
useUpdateFilters,
} from 'sentry/views/insights/pages/useFilters';
import {MODULE_TITLES} from 'sentry/views/insights/settings';
import {type InsightLandingProps, ModuleName} from 'sentry/views/insights/types';
import {ModuleName} from 'sentry/views/insights/types';

function MobileLandingPage() {
const filters = useFilters();
const updateFilters = useUpdateFilters();

const landingPageProps: InsightLandingProps = {disableHeader: true};

const crumbs: Crumb[] = [
{
label: t('Performance'),
Expand Down Expand Up @@ -78,12 +76,8 @@ function MobileLandingPage() {
</Layout.Header>
<Layout.Main fullWidth>
<PageAlert />
<TabPanels>
<TabPanels.Item key={OVERVIEW_PAGE_TITLE}>{'overview page'}</TabPanels.Item>
<TabPanels.Item key={ModuleName.MOBILE_SCREENS}>
<ScreensLandingPage {...landingPageProps} />
</TabPanels.Item>
</TabPanels>
{!filters.module && 'overview page'}
{filters.module && <ModuleRenderer />}
</Layout.Main>
</Tabs>
</Fragment>
Expand Down
55 changes: 55 additions & 0 deletions static/app/views/insights/pages/moduleRenderer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import ResourcesLandingPage from 'sentry/views/insights/browser/resources/views/resourcesLandingPage';
import ResourceSummaryPage from 'sentry/views/insights/browser/resources/views/resourceSummaryPage';
import PageOverview from 'sentry/views/insights/browser/webVitals/views/pageOverview';
import WebVitalsLandingPage from 'sentry/views/insights/browser/webVitals/views/webVitalsLandingPage';
import CachesLandingPage from 'sentry/views/insights/cache/views/cacheLandingPage';
import DatabaseLandingPage from 'sentry/views/insights/database/views//databaseLandingPage';
import HTTPDomainSummaryPage from 'sentry/views/insights/http/views/httpDomainSummaryPage';
import HTTPLandingPage from 'sentry/views/insights/http/views/httpLandingPage';
import LLMLandingPage from 'sentry/views/insights/llmMonitoring/views/llmMonitoringLandingPage';
import AppStartsLandingPage from 'sentry/views/insights/mobile/appStarts/views/appStartsLandingPage';
import ScreenLoadLandingPage from 'sentry/views/insights/mobile/screenload/views/screenloadLandingPage';
import ScreensLandingPage from 'sentry/views/insights/mobile/screens/views/screensLandingPage';
import MobileUiLandingPage from 'sentry/views/insights/mobile/ui/views/uiLandingPage';
import {useFilters} from 'sentry/views/insights/pages/useFilters';
import QueuesLandingPage from 'sentry/views/insights/queues/views/queuesLandingPage';
import {type InsightLandingProps, ModuleName} from 'sentry/views/insights/types';

export function ModuleRenderer() {
const {module, hasSubpage} = useFilters();

const landingProps: InsightLandingProps = {disableHeader: true};

const ModuleSubPage = hasSubpage && ModuleSubpages[module || ''];
const ModuleLandingPage = ModuleNameToComponent[module || ''];

if (ModuleSubPage) {
return <ModuleSubPage {...landingProps} />;
}

if (ModuleLandingPage) {
return <ModuleLandingPage {...landingProps} />;
}
return null;
}

const ModuleNameToComponent: Record<ModuleName, React.ComponentType> = {
[ModuleName.DB]: DatabaseLandingPage,
[ModuleName.HTTP]: HTTPLandingPage,
[ModuleName.CACHE]: CachesLandingPage,
[ModuleName.QUEUE]: QueuesLandingPage,
[ModuleName.AI]: LLMLandingPage,
[ModuleName.RESOURCE]: ResourcesLandingPage,
[ModuleName.VITAL]: WebVitalsLandingPage,
[ModuleName.MOBILE_UI]: MobileUiLandingPage,
[ModuleName.SCREEN_LOAD]: ScreenLoadLandingPage,
[ModuleName.MOBILE_SCREENS]: ScreensLandingPage,
[ModuleName.APP_START]: AppStartsLandingPage,
[ModuleName.OTHER]: () => null,
};

const ModuleSubpages: Partial<Record<ModuleName, React.ComponentType>> = {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Todo, fill this in

[ModuleName.RESOURCE]: ResourceSummaryPage,
[ModuleName.HTTP]: HTTPDomainSummaryPage,
[ModuleName.VITAL]: PageOverview,
};
Loading
Loading