feat(front) : maj @malio/layer-ui 1.7.1 et refonte des drawers
- adaptation a l'API MalioDrawer 1.7 (titre via slot #header, footer frere du body scrollable) - footer fixe : boutons 150px, justify-between, bordures header/footer - permissions en accordeon Malio par module (RoleDrawer + UserRbacDrawer) - cases a cocher sur une seule colonne - suppression de PermissionGroup, devenu inutilise Ajustements restants (layers/titres) a suivre.
This commit is contained in:
@@ -1,11 +1,17 @@
|
||||
<template>
|
||||
<MalioDrawer
|
||||
:model-value="modelValue"
|
||||
:title="t('admin.users.drawer.title', { username: user?.username ?? '' })"
|
||||
drawer-class="w-full max-w-lg"
|
||||
drawer-class="w-full max-w-[450px]"
|
||||
header-class="border-b border-black"
|
||||
footer-class="justify-between border-t border-black p-6"
|
||||
@update:model-value="emit('update:modelValue', $event)"
|
||||
>
|
||||
<div class="flex flex-col gap-6 p-4">
|
||||
<template #header>
|
||||
<h2 class="text-[24px] font-bold">
|
||||
{{ t('admin.users.drawer.title', { username: user?.username ?? '' }) }}
|
||||
</h2>
|
||||
</template>
|
||||
<div class="flex flex-col gap-4 py-4">
|
||||
<!-- Etat d'erreur de chargement des referentiels : bloque la
|
||||
sauvegarde pour empecher un ecrasement silencieux des droits. -->
|
||||
<div
|
||||
@@ -60,18 +66,39 @@
|
||||
<div v-if="permissionsByModule.length === 0" class="text-sm text-neutral-400">
|
||||
{{ t('admin.roles.permissions.noPermissions') }}
|
||||
</div>
|
||||
<div class="flex flex-col gap-4">
|
||||
<PermissionGroup
|
||||
<!-- Un panneau d'accordeon par module (mode multiple) ; le compteur
|
||||
selectionnees/total reste visible dans l'en-tete replie. -->
|
||||
<MalioAccordion v-else v-model="openDirectModules">
|
||||
<MalioAccordionItem
|
||||
v-for="group in permissionsByModule"
|
||||
:key="group.module"
|
||||
:module="group.module"
|
||||
:module-label="group.module"
|
||||
:permissions="group.permissions"
|
||||
:selected-ids="selectedDirectPermissionIds"
|
||||
@toggle="handleTogglePermission"
|
||||
@toggle-all="handleToggleAll"
|
||||
/>
|
||||
</div>
|
||||
:value="group.module"
|
||||
:title="`${group.module} (${directSelectedCount(group)}/${group.permissions.length})`"
|
||||
header-class="capitalize"
|
||||
>
|
||||
<div class="flex flex-col gap-3">
|
||||
<!-- Tout selectionner pour ce module -->
|
||||
<MalioCheckbox
|
||||
:id="`direct-group-${group.module}`"
|
||||
:label="t('admin.roles.permissions.selectAll')"
|
||||
:model-value="directAllSelected(group)"
|
||||
label-class="font-semibold text-sm text-neutral-700"
|
||||
@update:model-value="(val: boolean) => handleToggleAll(group.module, val)"
|
||||
/>
|
||||
<div class="flex flex-col gap-2">
|
||||
<MalioCheckbox
|
||||
v-for="perm in group.permissions"
|
||||
:id="`direct-perm-${perm.id}`"
|
||||
:key="perm.id"
|
||||
:label="perm.label"
|
||||
:model-value="selectedDirectPermissionIds.has(perm.id)"
|
||||
label-class="text-sm text-neutral-600"
|
||||
@update:model-value="(val: boolean) => handleTogglePermission(perm.id, val)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</MalioAccordionItem>
|
||||
</MalioAccordion>
|
||||
</div>
|
||||
|
||||
<!-- Section Sites autorises (ticket 2 module Sites) -->
|
||||
@@ -103,21 +130,25 @@
|
||||
<EffectivePermissions :permissions="effectivePermissions" />
|
||||
</div>
|
||||
|
||||
<!-- Boutons -->
|
||||
<div class="flex justify-end gap-3 border-t border-neutral-200 pt-4">
|
||||
<MalioButton
|
||||
:label="t('common.cancel')"
|
||||
variant="tertiary"
|
||||
@click="emit('update:modelValue', false)"
|
||||
/>
|
||||
<MalioButton
|
||||
:label="t('common.save')"
|
||||
variant="primary"
|
||||
:disabled="saving || loadFailed"
|
||||
@click="handleSave"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Footer fixe : depuis la 1.7.1 le slot #footer est un frere du body
|
||||
scrollable (shrink-0), donc reellement fige sans sticky. -->
|
||||
<template #footer>
|
||||
<MalioButton
|
||||
:label="t('common.cancel')"
|
||||
variant="tertiary"
|
||||
button-class="w-[150px]"
|
||||
@click="emit('update:modelValue', false)"
|
||||
/>
|
||||
<MalioButton
|
||||
:label="t('common.save')"
|
||||
variant="primary"
|
||||
button-class="w-[150px]"
|
||||
:disabled="saving || loadFailed"
|
||||
@click="handleSave"
|
||||
/>
|
||||
</template>
|
||||
</MalioDrawer>
|
||||
</template>
|
||||
|
||||
@@ -158,6 +189,19 @@ const selectedRoleIds = ref(new Set<number>())
|
||||
const selectedDirectPermissionIds = ref(new Set<number>())
|
||||
const selectedSiteIds = ref(new Set<number>())
|
||||
|
||||
// Modules ouverts dans l'accordeon des permissions directes (mode multiple)
|
||||
const openDirectModules = ref<string[]>([])
|
||||
|
||||
// Nombre de permissions directes selectionnees pour un module donne
|
||||
function directSelectedCount(group: PermissionModule): number {
|
||||
return group.permissions.filter(p => selectedDirectPermissionIds.value.has(p.id)).length
|
||||
}
|
||||
|
||||
// Vrai si toutes les permissions directes du module sont selectionnees
|
||||
function directAllSelected(group: PermissionModule): boolean {
|
||||
return group.permissions.length > 0 && directSelectedCount(group) === group.permissions.length
|
||||
}
|
||||
|
||||
// Detecter l'auto-edition
|
||||
const isSelfEdit = computed(() => props.user?.id === auth.user?.id)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user