Enrich the logged-in user with directory name + photo (by SSO)

When the employees directory is enabled, look up the current user by their SSO
(= username) and show their full name + photo in the sidebar user menu.

- auth store: enrichFromDirectory() runs on login + fetchUser; sets
  directoryname/directorypicture from employeesApi.lookup(sso). Best-effort -
  falls back to the raw SSO when employees is off, the SSO is not in the
  directory, or the lookup fails.
- displayName / avatarUrl getters; sidebar shows the photo (/static/employees/
  <Picture>) + name over the SSO. Broken photos hide gracefully.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
cproudlock
2026-07-10 11:36:00 -04:00
parent 24d5b00dc2
commit 301eaa6375
2 changed files with 46 additions and 5 deletions

View File

@@ -39,7 +39,12 @@
<div class="user-menu">
<template v-if="authStore.isAuthenticated">
<div class="username">{{ authStore.username }}</div>
<img v-if="authStore.avatarUrl" :src="authStore.avatarUrl" class="user-avatar"
:alt="authStore.displayName" @error="onAvatarError" />
<div class="user-ident">
<div class="username">{{ authStore.displayName }}</div>
<div v-if="authStore.displayName !== authStore.username" class="user-sso">{{ authStore.username }}</div>
</div>
<button class="btn btn-secondary" @click="handleLogout">Logout</button>
</template>
<router-link v-else to="/login" class="btn btn-primary">Login</router-link>
@@ -196,4 +201,16 @@ async function handleLogout() {
await authStore.logout()
router.push('/login')
}
// Hide a broken avatar (photo filename set but file missing).
function onAvatarError(event) {
event.target.style.display = 'none'
}
</script>
<style scoped>
.user-menu { display: flex; align-items: center; gap: 0.6rem; }
.user-avatar { width: 34px; height: 34px; border-radius: 50%; object-fit: cover; border: 1px solid var(--border); }
.user-ident { display: flex; flex-direction: column; line-height: 1.1; }
.user-sso { font-size: 0.72rem; color: var(--text-light); }
</style>