Skip to content

Commit a36b350

Browse files
authored
[HDX-3732] Fix AppNav crash for blank user names (#1934)
## Summary Fixes an AppNav crash caused by blank or whitespace-only user names. The user menu now normalizes the display name before generating avatar initials and includes a regression test for both whitespace-heavy and blank inputs. ### How to test locally or on Vercel 1. Open the app with a user whose name is blank or contains only whitespace and confirm the AppNav renders instead of crashing. 2. Run `cd packages/app && yarn ci:unit src/components/__tests__/AppNavUserMenu.test.tsx`. 3. Optionally run `make ci-lint` and `make ci-unit` to compare against current repo-wide CI status. ### References - Linear Issue: https://linear.app/clickhouse/issue/HDX-3732/bug-app-crashed-at-the-appnav-component - Related PRs: None
1 parent a03cecc commit a36b350

File tree

2 files changed

+41
-5
lines changed

2 files changed

+41
-5
lines changed

packages/app/src/components/AppNav/AppNav.components.tsx

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,20 +65,28 @@ type AppNavUserMenuProps = {
6565
onClickUserPreferences?: () => void;
6666
};
6767

68+
const getUserInitials = (userName: string) => {
69+
const nameParts = userName.trim().split(/\s+/).filter(Boolean);
70+
71+
if (nameParts.length === 0) {
72+
return 'U';
73+
}
74+
75+
return nameParts.map(name => name.charAt(0).toUpperCase()).join('');
76+
};
77+
6878
export const AppNavUserMenu = ({
6979
userName = 'User',
7080
teamName,
7181
logoutUrl,
7282
onClickUserPreferences,
7383
}: AppNavUserMenuProps) => {
7484
const { isCollapsed } = React.useContext(AppNavContext);
85+
const resolvedUserName = userName.trim() || 'User';
7586

76-
const initials = userName
77-
.split(' ')
78-
.map(name => name[0].toUpperCase())
79-
.join('');
87+
const initials = getUserInitials(resolvedUserName);
8088

81-
const displayName = IS_LOCAL_MODE ? 'Local mode' : userName;
89+
const displayName = IS_LOCAL_MODE ? 'Local mode' : resolvedUserName;
8290

8391
return (
8492
<Menu position="top-start" transitionProps={{ transition: 'fade-up' }}>
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import React from 'react';
2+
import { screen } from '@testing-library/react';
3+
4+
import { AppNavContext, AppNavUserMenu } from '../AppNav/AppNav.components';
5+
6+
const renderAppNavUserMenu = (userName?: string) => {
7+
return renderWithMantine(
8+
<AppNavContext.Provider value={{ isCollapsed: false, pathname: '/' }}>
9+
<AppNavUserMenu userName={userName} teamName="HyperDX" />
10+
</AppNavContext.Provider>,
11+
);
12+
};
13+
14+
describe('AppNavUserMenu', () => {
15+
it('renders initials for multi-word names with extra whitespace', () => {
16+
renderAppNavUserMenu(' Ada Lovelace ');
17+
18+
expect(screen.getByText('AL')).toBeInTheDocument();
19+
expect(screen.getByText(/Ada\s+Lovelace/)).toBeInTheDocument();
20+
});
21+
22+
it('falls back to the default user label for blank names', () => {
23+
renderAppNavUserMenu(' ');
24+
25+
expect(screen.getByText('U')).toBeInTheDocument();
26+
expect(screen.getByText('User')).toBeInTheDocument();
27+
});
28+
});

0 commit comments

Comments
 (0)