Skip to content

Commit f5fe6b0

Browse files
authored
feat(agents-insights): allow users to switch back to old view (#93930)
1 parent 67450ca commit f5fe6b0

File tree

11 files changed

+117
-13
lines changed

11 files changed

+117
-13
lines changed

static/app/components/sidebar/index.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ import {useLocation} from 'sentry/utils/useLocation';
5252
import useMedia from 'sentry/utils/useMedia';
5353
import useOrganization from 'sentry/utils/useOrganization';
5454
import {makeAlertsPathname} from 'sentry/views/alerts/pathnames';
55-
import {AgentInsightsFeature} from 'sentry/views/insights/agentMonitoring/utils/features';
55+
import {AIInsightsFeature} from 'sentry/views/insights/agentMonitoring/utils/features';
5656
import {MODULE_BASE_URLS} from 'sentry/views/insights/common/utils/useModuleURL';
5757
import {
5858
AGENTS_LANDING_SUB_PATH,
@@ -373,7 +373,7 @@ function Sidebar() {
373373
id="performance-domains-mobile"
374374
icon={<SubitemDot collapsed />}
375375
/>
376-
<AgentInsightsFeature
376+
<AIInsightsFeature
377377
organization={organization}
378378
renderDisabled={() => (
379379
<SidebarItem
@@ -392,7 +392,7 @@ function Sidebar() {
392392
id="performance-domains-agents"
393393
icon={<SubitemDot collapsed />}
394394
/>
395-
</AgentInsightsFeature>
395+
</AIInsightsFeature>
396396
<SidebarItem
397397
{...sidebarItemProps}
398398
label={t('Crons')}

static/app/types/user.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ export interface User extends Omit<AvatarUser, 'options'> {
5151
clock24Hours: boolean;
5252
defaultIssueEvent: 'recommended' | 'latest' | 'oldest';
5353
language: string;
54+
prefersAgentsInsightsModule: boolean;
5455
prefersChonkUI: boolean;
5556
prefersIssueDetailsStreamlinedUI: boolean | null;
5657
prefersNextjsInsightsOverview: boolean;
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import type {Key} from 'react';
2+
import styled from '@emotion/styled';
3+
4+
import DropdownButton from 'sentry/components/dropdownButton';
5+
import {DropdownMenu} from 'sentry/components/dropdownMenu';
6+
import {IconLab} from 'sentry/icons';
7+
import useMutateUserOptions from 'sentry/utils/useMutateUserOptions';
8+
import {useNavigate} from 'sentry/utils/useNavigate';
9+
import useOrganization from 'sentry/utils/useOrganization';
10+
import {
11+
hasAgentInsightsFeature,
12+
usePreferedAiModule,
13+
} from 'sentry/views/insights/agentMonitoring/utils/features';
14+
15+
export function AiModuleToggleButton() {
16+
const {mutate: mutateUserOptions} = useMutateUserOptions();
17+
const preferedAiModule = usePreferedAiModule();
18+
const navigate = useNavigate();
19+
const organization = useOrganization();
20+
21+
const togglePreferedModule = () => {
22+
const prefersAgentsInsightsModule = preferedAiModule === 'agents-insights';
23+
const newPrefersAgentsInsightsModule = !prefersAgentsInsightsModule;
24+
mutateUserOptions({
25+
['prefersAgentsInsightsModule']: newPrefersAgentsInsightsModule,
26+
});
27+
28+
return newPrefersAgentsInsightsModule;
29+
};
30+
31+
const handleExperimentDropdownAction = (key: Key) => {
32+
if (key === 'ai-module') {
33+
const prefersAgentsInsightsModule = togglePreferedModule();
34+
if (prefersAgentsInsightsModule) {
35+
navigate('/insights/agents');
36+
} else {
37+
navigate('/insights/ai/llm-monitoring');
38+
}
39+
}
40+
};
41+
42+
if (!hasAgentInsightsFeature(organization)) {
43+
return null;
44+
}
45+
46+
return (
47+
<DropdownMenu
48+
trigger={triggerProps => (
49+
<StyledDropdownButton {...triggerProps} size={'sm'}>
50+
{/* Passing icon as child to avoid extra icon margin */}
51+
<IconLab isSolid />
52+
</StyledDropdownButton>
53+
)}
54+
onAction={handleExperimentDropdownAction}
55+
items={[
56+
{
57+
key: 'ai-module',
58+
leadingItems:
59+
preferedAiModule === 'agents-insights' ? null : <IconLab isSolid />,
60+
label:
61+
preferedAiModule === 'agents-insights'
62+
? 'Switch to LLM Monitoring'
63+
: 'Switch to Agents Insights',
64+
},
65+
]}
66+
position="bottom-end"
67+
/>
68+
);
69+
}
70+
71+
const StyledDropdownButton = styled(DropdownButton)`
72+
color: ${p => p.theme.button.primary.background};
73+
:hover {
74+
color: ${p => p.theme.button.primary.background};
75+
}
76+
`;

static/app/views/insights/agentMonitoring/utils/features.tsx

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,34 @@
11
import Feature from 'sentry/components/acl/feature';
22
import {NoAccess} from 'sentry/components/noAccess';
33
import type {Organization} from 'sentry/types/organization';
4+
import useOrganization from 'sentry/utils/useOrganization';
5+
import {useUser} from 'sentry/utils/useUser';
46

57
type AgentInsightsFeatureProps = Omit<Parameters<typeof Feature>[0], 'features'>;
68

79
export function hasAgentInsightsFeature(organization: Organization) {
810
return organization.features.includes('agents-insights');
911
}
1012

11-
export function AgentInsightsFeature(props: AgentInsightsFeatureProps) {
13+
export function usePreferedAiModule() {
14+
const organization = useOrganization();
15+
const user = useUser();
16+
17+
if (!hasAgentInsightsFeature(organization)) {
18+
return 'llm-monitoring';
19+
}
20+
21+
return user.options.prefersAgentsInsightsModule ? 'agents-insights' : 'llm-monitoring';
22+
}
23+
24+
export function AIInsightsFeature(props: AgentInsightsFeatureProps) {
25+
const preferedAiModule = usePreferedAiModule();
26+
1227
return (
13-
<Feature features="agents-insights" renderDisabled={props.renderDisabled ?? NoAccess}>
28+
<Feature
29+
features={preferedAiModule}
30+
renderDisabled={props.renderDisabled ?? NoAccess}
31+
>
1432
{props.children}
1533
</Feature>
1634
);

static/app/views/insights/agentMonitoring/views/agentsOverviewPage.tsx

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {space} from 'sentry/styles/space';
1313
import {useLocation} from 'sentry/utils/useLocation';
1414
import useOrganization from 'sentry/utils/useOrganization';
1515
import {limitMaxPickableDays} from 'sentry/views/explore/utils';
16+
import {AiModuleToggleButton} from 'sentry/views/insights/agentMonitoring/components/aiModuleToggleButton';
1617
import LLMGenerationsWidget from 'sentry/views/insights/agentMonitoring/components/llmGenerationsWidget';
1718
import {ModelsTable} from 'sentry/views/insights/agentMonitoring/components/modelsTable';
1819
import TokenUsageWidget from 'sentry/views/insights/agentMonitoring/components/tokenUsageWidget';
@@ -23,7 +24,7 @@ import {
2324
TableType,
2425
useActiveTable,
2526
} from 'sentry/views/insights/agentMonitoring/hooks/useActiveTable';
26-
import {AgentInsightsFeature} from 'sentry/views/insights/agentMonitoring/utils/features';
27+
import {AIInsightsFeature} from 'sentry/views/insights/agentMonitoring/utils/features';
2728
import * as ModuleLayout from 'sentry/views/insights/common/components/moduleLayout';
2829
import {ModulePageProviders} from 'sentry/views/insights/common/components/modulePageProviders';
2930
import {ModuleBodyUpsellHook} from 'sentry/views/insights/common/components/moduleUpsellHookWrapper';
@@ -56,7 +57,10 @@ function AgentsMonitoringPage() {
5657

5758
return (
5859
<React.Fragment>
59-
<AgentsPageHeader module={ModuleName.AGENTS} />
60+
<AgentsPageHeader
61+
module={ModuleName.AGENTS}
62+
headerActions={<AiModuleToggleButton />}
63+
/>
6064
<ModuleBodyUpsellHook moduleName={ModuleName.AGENTS}>
6165
<Layout.Body>
6266
<Layout.Main fullWidth>
@@ -130,14 +134,14 @@ function AgentsMonitoringPage() {
130134

131135
function PageWithProviders() {
132136
return (
133-
<AgentInsightsFeature>
137+
<AIInsightsFeature>
134138
<ModulePageProviders
135139
moduleName={ModuleName.AGENTS}
136140
analyticEventName="insight.page_loads.agents"
137141
>
138142
<AgentsMonitoringPage />
139143
</ModulePageProviders>
140-
</AgentInsightsFeature>
144+
</AIInsightsFeature>
141145
);
142146
}
143147

static/app/views/insights/llmMonitoring/views/llmMonitoringLandingPage.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import * as Layout from 'sentry/components/layouts/thirds';
2+
import {AiModuleToggleButton} from 'sentry/views/insights/agentMonitoring/components/aiModuleToggleButton';
23
import * as ModuleLayout from 'sentry/views/insights/common/components/moduleLayout';
34
import {ModulePageFilterBar} from 'sentry/views/insights/common/components/modulePageFilterBar';
45
import {ModulePageProviders} from 'sentry/views/insights/common/components/modulePageProviders';
@@ -14,7 +15,7 @@ import {ModuleName} from 'sentry/views/insights/types';
1415
function LLMMonitoringPage() {
1516
return (
1617
<Layout.Page>
17-
<AiHeader module={ModuleName.AI} />
18+
<AiHeader module={ModuleName.AI} headerActions={<AiModuleToggleButton />} />
1819
<ModuleBodyUpsellHook moduleName={ModuleName.AI}>
1920
<Layout.Body>
2021
<Layout.Main fullWidth>

static/app/views/nav/secondary/sections/insights/insightsSecondaryNav.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import Feature from 'sentry/components/acl/feature';
55
import {t} from 'sentry/locale';
66
import useOrganization from 'sentry/utils/useOrganization';
77
import useProjects from 'sentry/utils/useProjects';
8-
import {AgentInsightsFeature} from 'sentry/views/insights/agentMonitoring/utils/features';
8+
import {AIInsightsFeature} from 'sentry/views/insights/agentMonitoring/utils/features';
99
import {MODULE_BASE_URLS} from 'sentry/views/insights/common/utils/useModuleURL';
1010
import {
1111
AGENTS_LANDING_SUB_PATH,
@@ -75,7 +75,7 @@ export function InsightsSecondaryNav() {
7575
{MOBILE_SIDEBAR_LABEL}
7676
</SecondaryNav.Item>
7777

78-
<AgentInsightsFeature
78+
<AIInsightsFeature
7979
organization={organization}
8080
renderDisabled={() => (
8181
<SecondaryNav.Item
@@ -92,7 +92,7 @@ export function InsightsSecondaryNav() {
9292
>
9393
{AGENTS_SIDEBAR_LABEL}
9494
</SecondaryNav.Item>
95-
</AgentInsightsFeature>
95+
</AIInsightsFeature>
9696
</SecondaryNav.Section>
9797
<SecondaryNav.Section id="insights-monitors">
9898
<SecondaryNav.Item to={`${baseUrl}/crons/`} analyticsItemName="insights_crons">

tests/js/fixtures/activityFeed.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ export function ActivityFeedFixture(params: Partial<Activity> = {}): Activity {
3535
timezone: 'America/Los_Angeles',
3636
prefersIssueDetailsStreamlinedUI: false,
3737
prefersNextjsInsightsOverview: false,
38+
prefersAgentsInsightsModule: false,
3839
prefersStackedNavigation: false,
3940
prefersChonkUI: false,
4041
quickStartDisplay: {},

tests/js/fixtures/commitAuthor.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ export function CommitAuthorFixture(params: Partial<User> = {}): User {
4141
prefersIssueDetailsStreamlinedUI: false,
4242
prefersStackedNavigation: false,
4343
prefersNextjsInsightsOverview: false,
44+
prefersAgentsInsightsModule: false,
4445
prefersChonkUI: false,
4546
quickStartDisplay: {},
4647
},

tests/js/fixtures/user.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export function UserFixture(params: Partial<User> = {}): User {
1818
prefersIssueDetailsStreamlinedUI: true,
1919
prefersStackedNavigation: false,
2020
prefersNextjsInsightsOverview: false,
21+
prefersAgentsInsightsModule: false,
2122
prefersChonkUI: false,
2223
quickStartDisplay: {},
2324
},

0 commit comments

Comments
 (0)