fix(sidebar) : items contextuels projet insérés sous « Projets » (et non en fin de groupe)

This commit is contained in:
2026-06-25 17:21:05 +02:00
parent 32c5d66968
commit a1b3c91613
+27 -8
View File
@@ -91,15 +91,20 @@ const SECTION_ICON: Record<string, string> = {
'sidebar.admin.section': 'mdi:cog-outline',
}
// Item client avec ancre optionnelle : `after` = `to` de l'item après lequel l'insérer
// (sinon ajouté en fin de section).
type ClientItem = MalioItem & { after?: string }
// Items rendus côté client (dépendent d'un état runtime ignoré du backend).
function clientItemsFor(key: string): MalioItem[] {
function clientItemsFor(key: string): ClientItem[] {
if (key === 'sidebar.general.section') {
const items: MalioItem[] = []
const items: ClientItem[] = []
if (currentProjectId.value) {
const id = currentProjectId.value
items.push({ label: t('sidebar.project.kanban'), to: `/projects/${id}`, exact: true })
items.push({ label: t('sidebar.project.groups'), to: `/projects/${id}/groups` })
items.push({ label: t('sidebar.project.archives'), to: `/projects/${id}/archives` })
// Insérés juste sous « Projets », dans l'ordre via ancres chaînées.
items.push({ label: t('sidebar.project.kanban'), to: `/projects/${id}`, exact: true, after: '/projects' })
items.push({ label: t('sidebar.project.groups'), to: `/projects/${id}/groups`, after: `/projects/${id}` })
items.push({ label: t('sidebar.project.archives'), to: `/projects/${id}/archives`, after: `/projects/${id}/groups` })
}
if (isEmployee.value) {
items.push({ label: t('sidebar.general.myAbsences'), to: '/absences' })
@@ -107,7 +112,7 @@ function clientItemsFor(key: string): MalioItem[] {
return items
}
if (key === 'sidebar.tools.section') {
const items: MalioItem[] = []
const items: ClientItem[] = []
if (isMailVisible.value) {
const n = mailStore.globalUnreadCount
const suffix = n > 0 ? ` (${n > 99 ? '99+' : n})` : ''
@@ -121,6 +126,20 @@ function clientItemsFor(key: string): MalioItem[] {
return []
}
// Insère les items client après leur ancre (`after`), sinon en fin de liste.
function mergeClientItems(base: MalioItem[], extra: ClientItem[]): MalioItem[] {
const result = [...base]
for (const { after, ...item } of extra) {
const idx = after ? result.findIndex((i) => i.to === after) : -1
if (idx !== -1) {
result.splice(idx + 1, 0, item)
} else {
result.push(item)
}
}
return result
}
const mergedSections = computed<MalioSection[]>(() => {
// 1. Sections backend (déjà filtrées par permissions), mail retiré (ré-injecté côté client).
const backend = new Map<string, MalioSection>()
@@ -140,12 +159,12 @@ const mergedSections = computed<MalioSection[]>(() => {
const base = backend.get(key)
const extra = clientItemsFor(key)
if (base) {
base.items.push(...extra)
base.items = mergeClientItems(base.items, extra)
if (base.items.length > 0) {
result.push(base)
}
} else if (extra.length > 0) {
result.push({ label: t(key), icon: SECTION_ICON[key] ?? '', items: extra })
result.push({ label: t(key), icon: SECTION_ICON[key] ?? '', items: mergeClientItems([], extra) })
}
}