refactor(frontend) : ERP-26 - migrate roles table to MalioDataTable component

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Matthieu
2026-04-16 09:32:54 +02:00
parent 07d53cdf8c
commit 3fe44e4de2

View File

@@ -14,70 +14,49 @@
</div> </div>
<!-- Table des roles --> <!-- Table des roles -->
<div class="mt-6 overflow-x-auto rounded-lg border border-neutral-200"> <MalioDataTable
<table v-if="roles.length > 0" class="w-full text-left text-sm"> class="mt-6"
<thead class="bg-neutral-50 text-xs uppercase text-neutral-500"> :columns="columns"
<tr> :items="roleItems"
<th class="px-4 py-3">{{ t('admin.roles.table.label') }}</th> :total-items="roles.length"
<th class="px-4 py-3">{{ t('admin.roles.table.code') }}</th> :row-clickable="true"
<th class="px-4 py-3 text-center">{{ t('admin.roles.table.permissions') }}</th> :empty-message="t('admin.roles.noRoles')"
<th class="px-4 py-3 text-center">{{ t('admin.roles.table.system') }}</th> @row-click="onRowClick"
<th class="px-4 py-3 text-right">{{ t('admin.roles.table.actions') }}</th> >
</tr> <template #cell-code="{ item }">
</thead> <span class="font-mono text-xs">{{ item.code }}</span>
<tbody class="divide-y divide-neutral-100"> </template>
<tr <template #cell-permissions="{ item }">
v-for="role in roles" {{ item.permissions }}
:key="role.id" </template>
class="cursor-pointer hover:bg-neutral-50 transition-colors" <template #cell-system="{ item }">
@click="openEditDrawer(role)" <span
> v-if="item.isSystem"
<td class="px-4 py-3 font-medium text-neutral-900"> class="inline-flex items-center rounded-full bg-blue-100 px-2.5 py-0.5 text-xs font-medium text-blue-800"
{{ role.label }} >
</td> {{ t('admin.roles.table.system') }}
<td class="px-4 py-3 font-mono text-xs text-neutral-500"> </span>
{{ role.code }} </template>
</td> <template #cell-actions="{ item }">
<td class="px-4 py-3 text-center text-neutral-600"> <div class="flex items-center justify-end gap-2" @click.stop>
{{ role.permissions.length }} <MalioButtonIcon
</td> v-if="can('core.roles.manage')"
<td class="px-4 py-3 text-center"> icon="mdi:pencil-outline"
<span :aria-label="t('common.edit')"
v-if="role.isSystem" variant="ghost"
class="inline-flex items-center rounded-full bg-blue-100 px-2.5 py-0.5 text-xs font-medium text-blue-800" @click="openEditDrawer(getRoleById(item.id as number)!)"
> />
{{ t('admin.roles.table.system') }} <MalioButtonIcon
</span> v-if="can('core.roles.manage')"
</td> icon="mdi:delete-outline"
<td class="px-4 py-3 text-right" @click.stop> :aria-label="t('common.delete')"
<div class="flex items-center justify-end gap-2"> variant="ghost"
<MalioButtonIcon :disabled="item.isSystem as boolean"
v-if="can('core.roles.manage')" @click="confirmDelete(getRoleById(item.id as number)!)"
icon="mdi:pencil-outline" />
:aria-label="t('common.edit')" </div>
variant="ghost" </template>
@click="openEditDrawer(role)" </MalioDataTable>
/>
<MalioButtonIcon
v-if="can('core.roles.manage')"
icon="mdi:delete-outline"
:aria-label="t('common.delete')"
variant="ghost"
:disabled="role.isSystem"
@click="confirmDelete(role)"
/>
</div>
</td>
</tr>
</tbody>
</table>
<!-- Etat vide -->
<div v-else class="flex flex-col items-center justify-center py-12 text-neutral-400">
<Icon name="mdi:shield-off-outline" class="mb-3 size-12" />
<p class="text-sm">{{ t('admin.roles.noRoles') }}</p>
</div>
</div>
<!-- Drawer creation/edition --> <!-- Drawer creation/edition -->
<RoleDrawer <RoleDrawer
@@ -122,6 +101,36 @@ useHead({ title: t('admin.roles.title') })
const roles = ref<Role[]>([]) const roles = ref<Role[]>([])
const loading = ref(false) const loading = ref(false)
const columns = [
{ key: 'label', label: t('admin.roles.table.label') },
{ key: 'code', label: t('admin.roles.table.code') },
{ key: 'permissions', label: t('admin.roles.table.permissions') },
{ key: 'system', label: t('admin.roles.table.system') },
{ key: 'actions', label: t('admin.roles.table.actions') },
]
// Transformer les roles en items compatibles MalioDataTable
const roleItems = computed(() =>
roles.value.map(role => ({
id: role.id,
label: role.label,
code: role.code,
permissions: role.permissions.length,
isSystem: role.isSystem,
system: '', // colonne geree par le slot
actions: '', // colonne geree par le slot
}))
)
function getRoleById(id: number): Role | undefined {
return roles.value.find(r => r.id === id)
}
function onRowClick(item: Record<string, unknown>) {
const role = getRoleById(item.id as number)
if (role) openEditDrawer(role)
}
const drawerOpen = ref(false) const drawerOpen = ref(false)
const selectedRole = ref<Role | null>(null) const selectedRole = ref<Role | null>(null)
const deleteModalOpen = ref(false) const deleteModalOpen = ref(false)