diff --git a/static/app/components/sidebar/index.spec.tsx b/static/app/components/sidebar/index.spec.tsx index bcd81f848faceb..1a47c6e80f80d5 100644 --- a/static/app/components/sidebar/index.spec.tsx +++ b/static/app/components/sidebar/index.spec.tsx @@ -78,6 +78,28 @@ describe('Sidebar', function () { await userEvent.click(screen.getByTestId('sidebar-dropdown')); }); + it('renders for self-hosted errors only', async function () { + act(() => void ConfigStore.set('isSelfHostedErrorsOnly', true)); + const {container} = renderSidebar({organization}); + expect(await screen.findByTestId('sidebar-dropdown')).toBeInTheDocument(); + const sidebarItems = container.querySelectorAll('[id^="sidebar-item"]'); + const sidebarItemIds = Array.from(sidebarItems).map(sidebarItem => sidebarItem.id); + expect(sidebarItems.length).toEqual(10); + expect(sidebarItemIds).toEqual([ + 'sidebar-item-issues', + 'sidebar-item-projects', + 'sidebar-item-alerts', + 'sidebar-item-releases', + 'sidebar-item-stats', + 'sidebar-item-settings', + 'sidebar-item-help', + 'sidebar-item-broadcasts', + 'sidebar-item-statusupdate', + 'sidebar-item-collapse', + ]); + act(() => void ConfigStore.set('isSelfHostedErrorsOnly', false)); + }); + it('has can logout', async function () { const mock = MockApiClient.addMockResponse({ url: '/auth/', @@ -274,15 +296,93 @@ describe('Sidebar', function () { }); describe('when the accordion is used', () => { - const renderSidebarWithFeatures = () => { - renderSidebar({ + const renderSidebarWithFeatures = (features: string[] = []) => { + return renderSidebar({ organization: { ...organization, - features: [...organization.features, ...sidebarAccordionFeatures], + features: [...organization.features, ...sidebarAccordionFeatures, ...features], }, }); }; + it('renders sidebar with features', async function () { + const {container} = renderSidebarWithFeatures(); + expect(await screen.findByTestId('sidebar-dropdown')).toBeInTheDocument(); + const sidebarItems = container.querySelectorAll('[id^="sidebar-item"]'); + const sidebarItemIds = Array.from(sidebarItems).map(sidebarItem => sidebarItem.id); + expect(sidebarItems.length).toEqual(12); + expect(sidebarItemIds).toEqual([ + 'sidebar-item-issues', + 'sidebar-item-projects', + 'sidebar-item-sidebar-accordion-performance-item', + 'sidebar-item-crons', + 'sidebar-item-alerts', + 'sidebar-item-releases', + 'sidebar-item-stats', + 'sidebar-item-settings', + 'sidebar-item-help', + 'sidebar-item-broadcasts', + 'sidebar-item-statusupdate', + 'sidebar-item-collapse', + ]); + }); + + it('renders new sidebar hierarchy', async function () { + const {container} = renderSidebarWithFeatures([ + 'performance-insights', + 'insights-entry-points', + ]); + expect(await screen.findByTestId('sidebar-dropdown')).toBeInTheDocument(); + const sidebarItems = container.querySelectorAll('[id^="sidebar-item"]'); + const sidebarItemIds = Array.from(sidebarItems).map(sidebarItem => sidebarItem.id); + expect(sidebarItems.length).toEqual(21); + expect(sidebarItemIds).toEqual([ + 'sidebar-item-issues', + 'sidebar-item-projects', + 'sidebar-item-sidebar-accordion-explore-item', + 'sidebar-item-sidebar-accordion-insights-item', + 'sidebar-item-performance-http', + 'sidebar-item-performance-database', + 'sidebar-item-performance-browser-resources', + 'sidebar-item-performance-mobile-app-startup', + 'sidebar-item-performance-mobile-screens', + 'sidebar-item-performance-webvitals', + 'sidebar-item-performance-cache', + 'sidebar-item-performance', + 'sidebar-item-crons', + 'sidebar-item-alerts', + 'sidebar-item-releases', + 'sidebar-item-stats', + 'sidebar-item-settings', + 'sidebar-item-help', + 'sidebar-item-broadcasts', + 'sidebar-item-statusupdate', + 'sidebar-item-collapse', + ]); + }); + + it('renders sidebar items for self-hosted errors only', async function () { + act(() => void ConfigStore.set('isSelfHostedErrorsOnly', true)); + const {container} = renderSidebarWithFeatures(); + expect(await screen.findByTestId('sidebar-dropdown')).toBeInTheDocument(); + const sidebarItems = container.querySelectorAll('[id^="sidebar-item"]'); + const sidebarItemIds = Array.from(sidebarItems).map(sidebarItem => sidebarItem.id); + expect(sidebarItems.length).toEqual(10); + expect(sidebarItemIds).toEqual([ + 'sidebar-item-issues', + 'sidebar-item-projects', + 'sidebar-item-alerts', + 'sidebar-item-releases', + 'sidebar-item-stats', + 'sidebar-item-settings', + 'sidebar-item-help', + 'sidebar-item-broadcasts', + 'sidebar-item-statusupdate', + 'sidebar-item-collapse', + ]); + act(() => void ConfigStore.set('isSelfHostedErrorsOnly', false)); + }); + it('should not render floating accordion when expanded', async () => { renderSidebarWithFeatures(); await userEvent.click(screen.getByTestId('sidebar-accordion-performance-item')); diff --git a/static/app/components/sidebar/index.tsx b/static/app/components/sidebar/index.tsx index 47aada29c2c3bb..a3ff2401eee04b 100644 --- a/static/app/components/sidebar/index.tsx +++ b/static/app/components/sidebar/index.tsx @@ -130,6 +130,7 @@ function Sidebar() { const organization = useOrganization({allowNull: true}); const {shouldAccordionFloat} = useContext(ExpandedContext); const resourceModuleTitle = useModuleTitle(ModuleName.RESOURCE); + const isSelfHostedErrorsOnly = ConfigStore.get('isSelfHostedErrorsOnly'); const collapsed = !!preferences.collapsed; const horizontal = useMedia(`(max-width: ${theme.breakpoints.medium})`); @@ -671,7 +672,7 @@ function Sidebar() { {projects} - {hasNewSidebarHierarchy && ( + {hasNewSidebarHierarchy && !isSelfHostedErrorsOnly && ( {explore} @@ -689,7 +690,7 @@ function Sidebar() { )} - {!hasNewSidebarHierarchy && ( + {!hasNewSidebarHierarchy && !isSelfHostedErrorsOnly && ( {performance} @@ -711,6 +712,18 @@ function Sidebar() { )} + {isSelfHostedErrorsOnly && ( + + + {alerts} + {discover2} + {dashboards} + {releases} + {userFeedback} + + + )} + {stats} {settings} diff --git a/static/app/types/system.tsx b/static/app/types/system.tsx index ab0cb73d7519ca..aa0aa80600941a 100644 --- a/static/app/types/system.tsx +++ b/static/app/types/system.tsx @@ -150,6 +150,7 @@ export interface Config { // Maintain isOnPremise key for backcompat (plugins?). isOnPremise: boolean; isSelfHosted: boolean; + isSelfHostedErrorsOnly: boolean; languageCode: string; lastOrganization: string | null; links: { diff --git a/tests/js/fixtures/config.ts b/tests/js/fixtures/config.ts index 41de61b2085fb4..4526150dcab492 100644 --- a/tests/js/fixtures/config.ts +++ b/tests/js/fixtures/config.ts @@ -25,6 +25,7 @@ export function ConfigFixture(params: Partial = {}): Config { // Maintain isOnPremise key for backcompat (plugins?). isOnPremise: false, isSelfHosted: false, + isSelfHostedErrorsOnly: false, lastOrganization: null, gravatarBaseUrl: 'https://gravatar.com', initialTrace: {