mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-03-11 08:00:21 +00:00
feat: show user avatar for personal workspace (#9687)
Use the login provider's profile picture (Google, GitHub, etc.) as the topbar avatar when in the personal workspace, instead of the generated gradient letter avatar. <img width="371" height="563" alt="Screenshot 2026-03-09 at 6 45 11 PM" src="https://github.com/user-attachments/assets/29dc0d87-0bdb-497c-ab1d-f8d4d6784217" /> - Fixes # ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-9687-feat-show-user-avatar-for-personal-workspace-31f6d73d36508191ab34fe7880e5e57e) by [Unito](https://www.unito.io) --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -9,6 +9,18 @@ import enMessages from '@/locales/en/main.json' with { type: 'json' }
|
||||
|
||||
import CurrentUserButton from './CurrentUserButton.vue'
|
||||
|
||||
const mockFeatureFlags = vi.hoisted(() => ({
|
||||
teamWorkspacesEnabled: false
|
||||
}))
|
||||
|
||||
const mockTeamWorkspaceStore = vi.hoisted(() => ({
|
||||
workspaceName: { value: '' },
|
||||
initState: { value: 'idle' },
|
||||
isInPersonalWorkspace: { value: false }
|
||||
}))
|
||||
|
||||
const mockIsCloud = vi.hoisted(() => ({ value: false }))
|
||||
|
||||
// Mock all firebase modules
|
||||
vi.mock('firebase/app', () => ({
|
||||
initializeApp: vi.fn(),
|
||||
@@ -32,16 +44,19 @@ vi.mock('pinia', () => ({
|
||||
// Mock the useFeatureFlags composable
|
||||
vi.mock('@/composables/useFeatureFlags', () => ({
|
||||
useFeatureFlags: vi.fn(() => ({
|
||||
flags: { teamWorkspacesEnabled: false }
|
||||
flags: mockFeatureFlags
|
||||
}))
|
||||
}))
|
||||
|
||||
// Mock the useTeamWorkspaceStore
|
||||
vi.mock('@/platform/workspace/stores/teamWorkspaceStore', () => ({
|
||||
useTeamWorkspaceStore: vi.fn(() => ({
|
||||
workspaceName: { value: '' },
|
||||
initState: { value: 'idle' }
|
||||
}))
|
||||
useTeamWorkspaceStore: vi.fn(() => mockTeamWorkspaceStore)
|
||||
}))
|
||||
|
||||
vi.mock('@/platform/distribution/types', () => ({
|
||||
get isCloud() {
|
||||
return mockIsCloud.value
|
||||
}
|
||||
}))
|
||||
|
||||
// Mock the useCurrentUser composable
|
||||
@@ -64,6 +79,16 @@ vi.mock('@/components/common/UserAvatar.vue', () => ({
|
||||
}
|
||||
}))
|
||||
|
||||
// Mock the WorkspaceProfilePic component
|
||||
vi.mock('@/platform/workspace/components/WorkspaceProfilePic.vue', () => ({
|
||||
default: {
|
||||
name: 'WorkspaceProfilePicMock',
|
||||
render() {
|
||||
return h('div', 'WorkspaceProfilePic')
|
||||
}
|
||||
}
|
||||
}))
|
||||
|
||||
// Mock the CurrentUserPopoverLegacy component
|
||||
vi.mock('./CurrentUserPopoverLegacy.vue', () => ({
|
||||
default: {
|
||||
@@ -78,9 +103,15 @@ vi.mock('./CurrentUserPopoverLegacy.vue', () => ({
|
||||
describe('CurrentUserButton', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
mockFeatureFlags.teamWorkspacesEnabled = false
|
||||
mockTeamWorkspaceStore.workspaceName.value = ''
|
||||
mockTeamWorkspaceStore.initState.value = 'idle'
|
||||
mockTeamWorkspaceStore.isInPersonalWorkspace.value = false
|
||||
mockIsCloud.value = false
|
||||
})
|
||||
|
||||
const mountComponent = (): VueWrapper => {
|
||||
const mountComponent = (options?: { stubButton?: boolean }): VueWrapper => {
|
||||
const { stubButton = true } = options ?? {}
|
||||
const i18n = createI18n({
|
||||
legacy: false,
|
||||
locale: 'en',
|
||||
@@ -99,7 +130,7 @@ describe('CurrentUserButton', () => {
|
||||
hide: vi.fn()
|
||||
}
|
||||
},
|
||||
Button: true
|
||||
...(stubButton ? { Button: true } : {})
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -137,4 +168,27 @@ describe('CurrentUserButton', () => {
|
||||
// Verify that popover.hide was called
|
||||
expect(popoverHideSpy).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('shows UserAvatar in personal workspace', () => {
|
||||
mockIsCloud.value = true
|
||||
mockFeatureFlags.teamWorkspacesEnabled = true
|
||||
mockTeamWorkspaceStore.initState.value = 'ready'
|
||||
mockTeamWorkspaceStore.isInPersonalWorkspace.value = true
|
||||
|
||||
const wrapper = mountComponent({ stubButton: false })
|
||||
expect(wrapper.html()).toContain('Avatar')
|
||||
expect(wrapper.html()).not.toContain('WorkspaceProfilePic')
|
||||
})
|
||||
|
||||
it('shows WorkspaceProfilePic in team workspace', () => {
|
||||
mockIsCloud.value = true
|
||||
mockFeatureFlags.teamWorkspacesEnabled = true
|
||||
mockTeamWorkspaceStore.initState.value = 'ready'
|
||||
mockTeamWorkspaceStore.isInPersonalWorkspace.value = false
|
||||
mockTeamWorkspaceStore.workspaceName.value = 'My Team'
|
||||
|
||||
const wrapper = mountComponent({ stubButton: false })
|
||||
expect(wrapper.html()).toContain('WorkspaceProfilePic')
|
||||
expect(wrapper.html()).not.toContain('Avatar')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -98,15 +98,21 @@ const photoURL = computed<string | undefined>(
|
||||
() => userPhotoUrl.value ?? undefined
|
||||
)
|
||||
|
||||
const { workspaceName: teamWorkspaceName, initState } = storeToRefs(
|
||||
useTeamWorkspaceStore()
|
||||
)
|
||||
const {
|
||||
workspaceName: teamWorkspaceName,
|
||||
initState,
|
||||
isInPersonalWorkspace
|
||||
} = storeToRefs(useTeamWorkspaceStore())
|
||||
|
||||
const showWorkspaceSkeleton = computed(
|
||||
() => isCloud && teamWorkspacesEnabled.value && initState.value === 'loading'
|
||||
)
|
||||
const showWorkspaceIcon = computed(
|
||||
() => isCloud && teamWorkspacesEnabled.value && initState.value === 'ready'
|
||||
() =>
|
||||
isCloud &&
|
||||
teamWorkspacesEnabled.value &&
|
||||
initState.value === 'ready' &&
|
||||
!isInPersonalWorkspace.value
|
||||
)
|
||||
|
||||
const workspaceName = computed(() => {
|
||||
|
||||
Reference in New Issue
Block a user