feat(mail) : sidebar — lien Messagerie + badge unread + polling lifecycle (start au login, stop au logout)

This commit is contained in:
2026-05-20 00:57:41 +02:00
parent 7c0d3372a9
commit 4d7ff9be26

View File

@@ -53,6 +53,23 @@
:collapsed="sidebarIsCollapsed" :collapsed="sidebarIsCollapsed"
@click="ui.closeMobileSidebar()" @click="ui.closeMobileSidebar()"
/> />
<div v-if="isMailVisible" class="relative">
<SidebarLink
to="/mail"
icon="mdi:email-outline"
:label="$t('mail.sidebar.title')"
:collapsed="sidebarIsCollapsed"
@click="ui.closeMobileSidebar()"
/>
<span
v-if="mailStore.globalUnreadCount > 0"
class="pointer-events-none absolute right-3 top-1/2 flex h-5 min-w-5 -translate-y-1/2 items-center justify-center rounded-full bg-red-500 px-1 text-xs font-bold text-white"
:class="{ 'right-1 top-1 translate-y-0': sidebarIsCollapsed }"
:aria-label="`${mailStore.globalUnreadCount} messages non lus`"
>
{{ mailStore.globalUnreadCount > 99 ? '99+' : mailStore.globalUnreadCount }}
</span>
</div>
<SidebarLink <SidebarLink
to="/projects" to="/projects"
icon="mdi:folder-outline" icon="mdi:folder-outline"
@@ -162,9 +179,18 @@ import { extractHydraMembers } from '~/utils/api'
const auth = useAuthStore() const auth = useAuthStore()
const ui = useUiStore() const ui = useUiStore()
const mailStore = useMailStore()
const {version} = useAppVersion() const {version} = useAppVersion()
const route = useRoute() const route = useRoute()
const isMailVisible = computed(() => {
const roles: string[] = auth.user?.roles ?? []
const isClientOnly = roles.includes('ROLE_CLIENT')
&& !roles.includes('ROLE_ADMIN')
&& !roles.includes('ROLE_USER')
return !isClientOnly && (roles.includes('ROLE_USER') || roles.includes('ROLE_ADMIN'))
})
// On mobile, sidebar is always expanded (not collapsed icon mode) // On mobile, sidebar is always expanded (not collapsed icon mode)
const sidebarIsCollapsed = computed(() => { const sidebarIsCollapsed = computed(() => {
if (ui.sidebarOpen) return false if (ui.sidebarOpen) return false
@@ -207,6 +233,17 @@ watch(
onMounted(() => { onMounted(() => {
timerStore.fetchActive() timerStore.fetchActive()
if (isMailVisible.value) {
mailStore.startPolling()
}
})
watch(() => auth.user, (user) => {
if (!user) {
mailStore.stopPolling()
} else if (isMailVisible.value) {
mailStore.startPolling()
}
}) })
const completeDrawerOpen = ref(false) const completeDrawerOpen = ref(false)