refactor(i18n) : sidebar.sites.admin + cles audit.entity.*
T-011 — deplace la cle sidebar.core.sites sous son module owner (sidebar.sites.admin). Aligne sur la convention naming.md : les cles sidebar doivent vivre sous le namespace du module qui expose l'item. T-015 — traduit entityType dans la page d'audit via des cles i18n audit.entity.core_user / core_role / core_permission / sites_site. Helper formatEntityType avec fallback sur l'identifiant brut pour rester debug-friendly si une traduction manque. Applique sur : - la cellule du tableau (tooltip garde l'identifiant technique) - les options du filtre multi-select MalioSelectCheckbox - le titre du drawer de detail + h3 interne
This commit is contained in:
@@ -77,7 +77,7 @@ return [
|
||||
'permission' => 'core.users.view',
|
||||
],
|
||||
[
|
||||
'label' => 'sidebar.core.sites',
|
||||
'label' => 'sidebar.sites.admin',
|
||||
'to' => '/admin/sites',
|
||||
'icon' => 'mdi:domain',
|
||||
'module' => 'sites',
|
||||
|
||||
@@ -28,8 +28,10 @@
|
||||
"core": {
|
||||
"roles": "Gestion des rôles",
|
||||
"users": "Utilisateurs",
|
||||
"sites": "Sites",
|
||||
"audit_log": "Journal d'audit"
|
||||
},
|
||||
"sites": {
|
||||
"admin": "Sites"
|
||||
}
|
||||
},
|
||||
"dashboard": {
|
||||
@@ -76,7 +78,10 @@
|
||||
"delete": "Suppression"
|
||||
},
|
||||
"entity": {
|
||||
"user": "Utilisateur"
|
||||
"core_user": "Utilisateur",
|
||||
"core_role": "Rôle",
|
||||
"core_permission": "Permission",
|
||||
"sites_site": "Site"
|
||||
},
|
||||
"empty": "Aucune activité enregistrée",
|
||||
"no_results": "Aucun résultat pour ces filtres",
|
||||
|
||||
@@ -115,7 +115,10 @@
|
||||
</span>
|
||||
</template>
|
||||
<template #cell-entityType="{ item }">
|
||||
<span class="font-mono text-xs">{{ item.entityType }}</span>
|
||||
<span
|
||||
class="text-xs"
|
||||
:title="item.entityType as string"
|
||||
>{{ formatEntityType(item.entityType as string) }}</span>
|
||||
</template>
|
||||
<template #cell-entityId="{ item }">
|
||||
<span class="font-mono text-xs">{{ item.entityId }}</span>
|
||||
@@ -134,8 +137,11 @@
|
||||
<div v-if="selectedEntry">
|
||||
<AuditLogDetail :entry="selectedEntry" />
|
||||
<div class="mt-4 border-t border-gray-200 pt-3">
|
||||
<h3 class="text-sm font-medium text-gray-700 mb-2">
|
||||
{{ selectedEntry.entityType }} #{{ selectedEntry.entityId }}
|
||||
<h3
|
||||
class="text-sm font-medium text-gray-700 mb-2"
|
||||
:title="selectedEntry.entityType"
|
||||
>
|
||||
{{ formatEntityType(selectedEntry.entityType) }} #{{ selectedEntry.entityId }}
|
||||
</h3>
|
||||
<AuditTimeline
|
||||
:entity-type="selectedEntry.entityType"
|
||||
@@ -151,10 +157,18 @@
|
||||
import { computed, nextTick, onMounted, reactive, ref, watch } from 'vue'
|
||||
import type { AuditLogEntry, AuditLogFilters } from '~/shared/types'
|
||||
|
||||
const { t } = useI18n()
|
||||
const { t, te } = useI18n()
|
||||
const { can } = usePermissions()
|
||||
const { fetchLogsCached, fetchEntityTypes } = useAuditLog()
|
||||
|
||||
// Traduit un identifiant `module.Entity` (ex: `core.User`, `sites.Site`) en
|
||||
// libelle lisible via la cle i18n `audit.entity.<module>_<entity>`. Si aucune
|
||||
// traduction n'existe, on retombe sur l'identifiant brut pour rester debug-friendly.
|
||||
function formatEntityType(type: string): string {
|
||||
const key = `audit.entity.${type.toLowerCase().replace(/\./g, '_')}`
|
||||
return te(key) ? t(key) : type
|
||||
}
|
||||
|
||||
// Protection cote UI : le middleware `modules.global.ts` filtre deja les
|
||||
// routes desactivees, mais si quelqu'un atterit ici sans la permission on
|
||||
// renvoie une 403 plutot que de flasher un ecran vide.
|
||||
@@ -180,8 +194,10 @@ const filters = reactive<AuditLogFilters>({
|
||||
// Attention : les composants Malio attendent `{ label, value }` (pas `{ text }`).
|
||||
const selectedEntityTypes = ref<(string | number)[]>([])
|
||||
const entityTypes = ref<string[]>([])
|
||||
// On garde l'identifiant technique comme `value` pour l'envoi API, mais on
|
||||
// affiche le libelle traduit quand il existe (fallback: identifiant brut).
|
||||
const entityTypeOptions = computed(() =>
|
||||
entityTypes.value.map(t => ({ value: t, label: t })),
|
||||
entityTypes.value.map(type => ({ value: type, label: formatEntityType(type) })),
|
||||
)
|
||||
|
||||
// Bind champ performedBy : MalioInputText attend `string | null`, on ne peut
|
||||
@@ -230,7 +246,7 @@ const rows = computed(() =>
|
||||
|
||||
const drawerTitle = computed(() =>
|
||||
selectedEntry.value
|
||||
? `${selectedEntry.value.entityType} #${selectedEntry.value.entityId}`
|
||||
? `${formatEntityType(selectedEntry.value.entityType)} #${selectedEntry.value.entityId}`
|
||||
: t('audit.detail_title'),
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user