Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
4 changes: 2 additions & 2 deletions web-app/src/components/ui/dropdown-menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ function DropdownMenuContent({
data-slot="dropdown-menu-content"
sideOffset={sideOffset}
className={cn(
'bg-main-view select-none text-main-view-fg border-main-view-fg/5 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md',
'bg-main-view select-none text-main-view-fg border-main-view-fg/5 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-[51] max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md',
className
)}
{...props}
Expand Down Expand Up @@ -229,7 +229,7 @@ function DropdownMenuSubContent({
<DropdownMenuPrimitive.SubContent
data-slot="dropdown-menu-sub-content"
className={cn(
'bg-main-view text-main-view-fg border-main-view-fg/5 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-lg',
'bg-main-view text-main-view-fg border-main-view-fg/5 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-[51] min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-lg',
className
)}
{...props}
Expand Down
1 change: 1 addition & 0 deletions web-app/src/containers/LeftPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@
return () => {
window.removeEventListener('resize', handleResize)
}
}, [setLeftPanel])

Check warning on line 144 in web-app/src/containers/LeftPanel.tsx

View workflow job for this annotation

GitHub Actions / test-on-macos

React Hook useEffect has a missing dependency: 'open'. Either include it or remove the dependency array

Check warning on line 144 in web-app/src/containers/LeftPanel.tsx

View workflow job for this annotation

GitHub Actions / base_branch_cov

React Hook useEffect has a missing dependency: 'open'. Either include it or remove the dependency array

Check warning on line 144 in web-app/src/containers/LeftPanel.tsx

View workflow job for this annotation

GitHub Actions / test-on-ubuntu

React Hook useEffect has a missing dependency: 'open'. Either include it or remove the dependency array

Check warning on line 144 in web-app/src/containers/LeftPanel.tsx

View workflow job for this annotation

GitHub Actions / test-on-windows-pr

React Hook useEffect has a missing dependency: 'open'. Either include it or remove the dependency array

Check warning on line 144 in web-app/src/containers/LeftPanel.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

React Hook useEffect has a missing dependency: 'open'. Either include it or remove the dependency array

const currentPath = useRouterState({
select: (state) => state.location.pathname,
Expand Down Expand Up @@ -433,6 +433,7 @@
if (menu.title === 'common:authentication') {
return (
<div key={menu.title}>
<div className="mx-1 my-2 border-t border-left-panel-fg/5" />
{isAuthenticated ? (
<UserProfileMenu />
) : (
Expand Down
41 changes: 39 additions & 2 deletions web-app/src/containers/auth/AuthLoginButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* Shows available authentication providers in a dropdown menu
*/

import { useState } from 'react'
import { useState, useRef, useEffect } from 'react'
import { IconLogin, IconBrandGoogleFilled } from '@tabler/icons-react'
import { useTranslation } from '@/i18n/react-i18next-compat'
import { useAuth } from '@/hooks/useAuth'
Expand All @@ -15,14 +15,45 @@ import {
DropdownMenuItem,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu'
import { useSmallScreen } from '@/hooks/useMediaQuery'

export const AuthLoginButton = () => {
const { t } = useTranslation()
const { getAllProviders, loginWithProvider } = useAuth()
const [isLoading, setIsLoading] = useState(false)
const [panelWidth, setPanelWidth] = useState<number>(192)
const dropdownRef = useRef<HTMLButtonElement>(null)
const isSmallScreen = useSmallScreen()

const enabledProviders = getAllProviders()

useEffect(() => {
const updateWidth = () => {
// Find the left panel element
const leftPanel = document.querySelector('aside[ref]') ||
document.querySelector('aside') ||
dropdownRef.current?.closest('aside')
if (leftPanel) {
setPanelWidth(leftPanel.getBoundingClientRect().width)
}
}

updateWidth()
window.addEventListener('resize', updateWidth)

// Also observe for panel resize
const observer = new ResizeObserver(updateWidth)
const leftPanel = document.querySelector('aside')
if (leftPanel) {
observer.observe(leftPanel)
}

return () => {
window.removeEventListener('resize', updateWidth)
observer.disconnect()
}
}, [])

const handleProviderLogin = async (providerId: ProviderType) => {
try {
setIsLoading(true)
Expand Down Expand Up @@ -52,14 +83,20 @@ export const AuthLoginButton = () => {
<DropdownMenu>
<DropdownMenuTrigger asChild>
<button
ref={dropdownRef}
disabled={isLoading}
className="flex items-center gap-1.5 cursor-pointer hover:bg-left-panel-fg/10 py-1 px-1 rounded w-full"
>
<IconLogin size={18} className="text-left-panel-fg/70" />
<span className="font-medium text-left-panel-fg/90">{t('common:login')}</span>
</button>
</DropdownMenuTrigger>
<DropdownMenuContent side="right" align="start" className="w-48">
<DropdownMenuContent
side="top"
align="end"
style={{ width: `${panelWidth}px` }}
alignOffset={isSmallScreen ? -4 : 0}
>
{enabledProviders.map((provider) => {
const IconComponent = getProviderIcon(provider.icon)
return (
Expand Down
69 changes: 49 additions & 20 deletions web-app/src/containers/auth/UserProfileMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* Dropdown menu with user profile and logout options
*/

import { useState } from 'react'
import { useState, useRef, useEffect } from 'react'
import {
DropdownMenu,
DropdownMenuContent,
Expand All @@ -13,16 +13,47 @@
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu'
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
import { Button } from '@/components/ui/button'

Check failure on line 16 in web-app/src/containers/auth/UserProfileMenu.tsx

View workflow job for this annotation

GitHub Actions / test-on-macos

'Button' is defined but never used

Check failure on line 16 in web-app/src/containers/auth/UserProfileMenu.tsx

View workflow job for this annotation

GitHub Actions / test-on-ubuntu

'Button' is defined but never used

Check failure on line 16 in web-app/src/containers/auth/UserProfileMenu.tsx

View workflow job for this annotation

GitHub Actions / test-on-windows-pr

'Button' is defined but never used

Check failure on line 16 in web-app/src/containers/auth/UserProfileMenu.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

'Button' is defined but never used
import { IconUser, IconLogout, IconChevronDown } from '@tabler/icons-react'

Check failure on line 17 in web-app/src/containers/auth/UserProfileMenu.tsx

View workflow job for this annotation

GitHub Actions / test-on-macos

'IconChevronDown' is defined but never used

Check failure on line 17 in web-app/src/containers/auth/UserProfileMenu.tsx

View workflow job for this annotation

GitHub Actions / test-on-ubuntu

'IconChevronDown' is defined but never used

Check failure on line 17 in web-app/src/containers/auth/UserProfileMenu.tsx

View workflow job for this annotation

GitHub Actions / test-on-windows-pr

'IconChevronDown' is defined but never used

Check failure on line 17 in web-app/src/containers/auth/UserProfileMenu.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

'IconChevronDown' is defined but never used
import { useTranslation } from '@/i18n/react-i18next-compat'
import { useAuth } from '@/hooks/useAuth'
import { toast } from 'sonner'
import { useSmallScreen } from '@/hooks/useMediaQuery'

export const UserProfileMenu = () => {
const { t } = useTranslation()
const { user, isLoading, logout } = useAuth()
const [isLoggingOut, setIsLoggingOut] = useState(false)
const [panelWidth, setPanelWidth] = useState<number>(192)
const dropdownRef = useRef<HTMLDivElement>(null)
const isSmallScreen = useSmallScreen()

useEffect(() => {
const updateWidth = () => {
// Find the left panel element
const leftPanel = document.querySelector('aside[ref]') ||
document.querySelector('aside') ||
dropdownRef.current?.closest('aside')
if (leftPanel) {
setPanelWidth(leftPanel.getBoundingClientRect().width)
}
}

updateWidth()
window.addEventListener('resize', updateWidth)

// Also observe for panel resize
const observer = new ResizeObserver(updateWidth)
const leftPanel = document.querySelector('aside')
if (leftPanel) {
observer.observe(leftPanel)
}

return () => {
window.removeEventListener('resize', updateWidth)
observer.disconnect()
}
}, [])

const handleLogout = async () => {
if (isLoggingOut) return
Expand Down Expand Up @@ -54,26 +85,24 @@
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
variant="link"
size="sm"
className="w-full justify-between gap-2 px-2"
>
<div className="flex items-center gap-2">
<Avatar className="h-6 w-6">
{user.picture && (
<AvatarImage src={user.picture} alt={user.name} />
)}
<AvatarFallback className="text-xs">
{getInitials(user.name)}
</AvatarFallback>
</Avatar>
<span className="truncate text-sm">{user.name}</span>
</div>
<IconChevronDown size={14} className="text-muted-foreground" />
</Button>
<div ref={dropdownRef} className="flex items-center gap-1.5 cursor-pointer hover:bg-left-panel-fg/10 py-1 px-1 rounded">
<Avatar className="h-[18px] w-[18px]">
{user.picture && (
<AvatarImage src={user.picture} alt={user.name} />
)}
<AvatarFallback className="text-[10px]">
{getInitials(user.name)}
</AvatarFallback>
</Avatar>
<span className="font-medium text-left-panel-fg/90">{user.name}</span>
</div>
</DropdownMenuTrigger>
<DropdownMenuContent side="right" align="start" className="w-56">
<DropdownMenuContent
side="top"
align="end"
style={{ width: `${panelWidth}px` }}
alignOffset={isSmallScreen ? -4 : 0}
>
<DropdownMenuLabel>
<div className="flex flex-col space-y-1">
<p className="text-sm font-medium leading-none">{user.name}</p>
Expand Down
Loading