6d3d44f0bb
- Bump @malio/layer-ui ^1.7.2 → ^1.7.3 - Migration des boutons d'action w-[150px] → w-m-btn-action (CategoryDrawer, RoleDrawer, SiteDrawer, UserRbacDrawer, audit-log) - Rabotage des gaps de formulaires pour absorber le slot message Malio desormais toujours rendu (forms drawers, listes de checkbox, grille dates audit-log, accordeon permissions) - Compensation des alignements verticaux pour les voisins non-Malio : puce couleur du SiteDrawer + labels Du/Au du drawer filtres audit-log - Reduction du padding lateral xl: dans le layout default (170px → 44px)
72 lines
3.0 KiB
Vue
72 lines
3.0 KiB
Vue
<template>
|
|
<!-- Accordeon de permissions groupees par module : un panneau par module,
|
|
avec compteur (selectionnees/total) dans le titre, case "Tout selectionner"
|
|
et liste des permissions individuelles. Source unique de cette UX, utilisee
|
|
par RoleDrawer (permissions du role) et UserRbacDrawer (permissions directes). -->
|
|
<MalioAccordion v-model="openModules">
|
|
<MalioAccordionItem
|
|
v-for="group in groupsByModule"
|
|
:key="group.module"
|
|
:value="group.module"
|
|
:title="`${group.module} (${selectedCountFor(group)}/${group.permissions.length})`"
|
|
header-class="capitalize"
|
|
>
|
|
<div class="flex flex-col">
|
|
<!-- Tout selectionner pour ce module -->
|
|
<MalioCheckbox
|
|
:id="`${idPrefix}-group-${group.module}`"
|
|
:label="t('admin.roles.permissions.selectAll')"
|
|
:model-value="allSelectedFor(group)"
|
|
label-class="font-semibold text-sm text-neutral-700"
|
|
@update:model-value="(val: boolean) => emit('toggle-all', group.module, val)"
|
|
/>
|
|
<div class="flex flex-col">
|
|
<MalioCheckbox
|
|
v-for="perm in group.permissions"
|
|
:id="`${idPrefix}-perm-${perm.id}`"
|
|
:key="perm.id"
|
|
:label="perm.label"
|
|
:model-value="selectedIds.has(perm.id)"
|
|
label-class="text-sm text-neutral-600"
|
|
@update:model-value="(val: boolean) => emit('toggle', perm.id, val)"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</MalioAccordionItem>
|
|
</MalioAccordion>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import type { PermissionModule } from '~/shared/types/rbac'
|
|
|
|
const { t } = useI18n()
|
|
|
|
const props = defineProps<{
|
|
/** Groupes de permissions a afficher, un par module. */
|
|
groupsByModule: PermissionModule[]
|
|
/** Ids des permissions actuellement selectionnees. */
|
|
selectedIds: Set<number>
|
|
/** Prefixe pour les ids HTML : evite les collisions si plusieurs accordeons coexistent (ex: "role" vs "direct"). */
|
|
idPrefix: string
|
|
}>()
|
|
|
|
const emit = defineEmits<{
|
|
toggle: [permissionId: number, selected: boolean]
|
|
'toggle-all': [module: string, selected: boolean]
|
|
}>()
|
|
|
|
// Modules ouverts dans l'accordeon (mode multiple). Etat local : chaque instance
|
|
// du composant garde sa propre liste, pas de partage entre drawers.
|
|
const openModules = ref<string[]>([])
|
|
|
|
// Nombre de permissions selectionnees pour un module donne.
|
|
function selectedCountFor(group: PermissionModule): number {
|
|
return group.permissions.filter(p => props.selectedIds.has(p.id)).length
|
|
}
|
|
|
|
// Vrai si toutes les permissions du module sont selectionnees.
|
|
function allSelectedFor(group: PermissionModule): boolean {
|
|
return group.permissions.length > 0 && selectedCountFor(group) === group.permissions.length
|
|
}
|
|
</script>
|