2a0918bbfe
Auto Tag Develop / tag (push) Successful in 9s
| Numéro du ticket | Titre du ticket | |------------------|-----------------| | | | ## Description de la PR ## Modification du .env ## Check list - [x] Pas de régression - [x] TU/TI/TF rédigée - [x] TU/TI/TF OK - [ ] CHANGELOG modifié Reviewed-on: #16 Co-authored-by: tristan <tristan@yuno.malio.fr> Co-committed-by: tristan <tristan@yuno.malio.fr>
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 gap-3">
|
|
<!-- 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 gap-2">
|
|
<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>
|