feat(audit) : filtres Employé et Utilisateur en champ texte (recherche libre)
Employé = recherche partielle sur nom/prénom (nouveau filtre back 'employee', LIKE via join) ; Utilisateur = recherche partielle sur username. Remplace les selects par des champs texte. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,12 +1,8 @@
|
||||
import { ref, computed } from 'vue'
|
||||
import type { AuditLog } from '~/services/dto/audit-log'
|
||||
import { fetchAuditLogs, type AuditLogFilters } from '~/services/audit-logs'
|
||||
import { listEmployees } from '~/services/employees'
|
||||
import { listUsers } from '~/services/users'
|
||||
|
||||
type Range = { start: string, end: string } | null
|
||||
type SelectOption = { value: number, text: string }
|
||||
type UsernameOption = { value: string, text: string }
|
||||
|
||||
export const useAuditLogsList = () => {
|
||||
const items = ref<AuditLog[]>([])
|
||||
@@ -15,11 +11,9 @@ export const useAuditLogsList = () => {
|
||||
const perPage = ref(10)
|
||||
const loading = ref(false)
|
||||
const filterOpen = ref(false)
|
||||
const employeeOptions = ref<SelectOption[]>([])
|
||||
const usernameOptions = ref<UsernameOption[]>([])
|
||||
|
||||
// Applied filters (drive the fetch)
|
||||
const appliedEmployeeId = ref<number | undefined>(undefined)
|
||||
const appliedEmployee = ref('')
|
||||
const appliedRange = ref<Range>(null)
|
||||
const appliedEntityTypes = ref<string[]>([])
|
||||
const appliedActions = ref<string[]>([])
|
||||
@@ -28,7 +22,7 @@ export const useAuditLogsList = () => {
|
||||
const appliedDevice = ref('')
|
||||
|
||||
// Draft filters (edited inside the drawer)
|
||||
const draftEmployeeId = ref<number | undefined>(undefined)
|
||||
const draftEmployee = ref('')
|
||||
const draftRange = ref<Range>(null)
|
||||
const draftEntityTypes = ref<string[]>([])
|
||||
const draftActions = ref<string[]>([])
|
||||
@@ -38,7 +32,7 @@ export const useAuditLogsList = () => {
|
||||
|
||||
const activeFilterCount = computed(() => {
|
||||
let n = 0
|
||||
if (appliedEmployeeId.value !== undefined) n++
|
||||
if (appliedEmployee.value.trim() !== '') n++
|
||||
if (appliedRange.value?.start || appliedRange.value?.end) n++
|
||||
if (appliedEntityTypes.value.length > 0) n++
|
||||
if (appliedActions.value.length > 0) n++
|
||||
@@ -49,7 +43,7 @@ export const useAuditLogsList = () => {
|
||||
})
|
||||
|
||||
const buildFilters = (): AuditLogFilters => ({
|
||||
employeeId: appliedEmployeeId.value,
|
||||
employee: appliedEmployee.value.trim() || undefined,
|
||||
from: appliedRange.value?.start || undefined,
|
||||
to: appliedRange.value?.end || undefined,
|
||||
entityType: appliedEntityTypes.value.length > 0 ? [...appliedEntityTypes.value] : undefined,
|
||||
@@ -79,23 +73,6 @@ export const useAuditLogsList = () => {
|
||||
}
|
||||
|
||||
const init = async () => {
|
||||
try {
|
||||
const employees = await listEmployees()
|
||||
employeeOptions.value = employees.map(e => ({
|
||||
value: e.id,
|
||||
text: `${e.lastName} ${e.firstName}`,
|
||||
}))
|
||||
} catch {
|
||||
employeeOptions.value = []
|
||||
}
|
||||
try {
|
||||
const users = await listUsers()
|
||||
usernameOptions.value = users
|
||||
.map(u => ({ value: u.username, text: u.username }))
|
||||
.sort((a, b) => a.text.localeCompare(b.text))
|
||||
} catch {
|
||||
usernameOptions.value = []
|
||||
}
|
||||
await load()
|
||||
}
|
||||
|
||||
@@ -111,7 +88,7 @@ export const useAuditLogsList = () => {
|
||||
}
|
||||
|
||||
const openFilters = () => {
|
||||
draftEmployeeId.value = appliedEmployeeId.value
|
||||
draftEmployee.value = appliedEmployee.value
|
||||
draftRange.value = appliedRange.value ? { ...appliedRange.value } : null
|
||||
draftEntityTypes.value = [...appliedEntityTypes.value]
|
||||
draftActions.value = [...appliedActions.value]
|
||||
@@ -122,7 +99,7 @@ export const useAuditLogsList = () => {
|
||||
}
|
||||
|
||||
const applyFilters = () => {
|
||||
appliedEmployeeId.value = draftEmployeeId.value
|
||||
appliedEmployee.value = draftEmployee.value
|
||||
appliedRange.value = draftRange.value ? { ...draftRange.value } : null
|
||||
appliedEntityTypes.value = [...draftEntityTypes.value]
|
||||
appliedActions.value = [...draftActions.value]
|
||||
@@ -135,14 +112,14 @@ export const useAuditLogsList = () => {
|
||||
}
|
||||
|
||||
const resetFilters = () => {
|
||||
draftEmployeeId.value = undefined
|
||||
draftEmployee.value = ''
|
||||
draftRange.value = null
|
||||
draftEntityTypes.value = []
|
||||
draftActions.value = []
|
||||
draftUsername.value = ''
|
||||
draftIp.value = ''
|
||||
draftDevice.value = ''
|
||||
appliedEmployeeId.value = undefined
|
||||
appliedEmployee.value = ''
|
||||
appliedRange.value = null
|
||||
appliedEntityTypes.value = []
|
||||
appliedActions.value = []
|
||||
@@ -160,8 +137,8 @@ export const useAuditLogsList = () => {
|
||||
const toggleAction = (value: string, selected: boolean) => toggle(draftActions, value, selected)
|
||||
|
||||
return {
|
||||
items, total, page, perPage, loading, filterOpen, employeeOptions, usernameOptions, activeFilterCount,
|
||||
draftEmployeeId, draftRange, draftEntityTypes, draftActions, draftUsername, draftIp, draftDevice,
|
||||
items, total, page, perPage, loading, filterOpen, activeFilterCount,
|
||||
draftEmployee, draftRange, draftEntityTypes, draftActions, draftUsername, draftIp, draftDevice,
|
||||
init, goToPage, setPerPage, openFilters, applyFilters, resetFilters, toggleEntityType, toggleAction,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,11 +63,7 @@
|
||||
</MalioAccordionItem>
|
||||
|
||||
<MalioAccordionItem title="Employé" value="employee">
|
||||
<MalioSelect
|
||||
v-model="list.draftEmployeeId.value"
|
||||
:options="list.employeeOptions.value"
|
||||
empty-option-label="Tous"
|
||||
/>
|
||||
<MalioInputText v-model="list.draftEmployee.value" icon-name="mdi:magnify" />
|
||||
</MalioAccordionItem>
|
||||
|
||||
<MalioAccordionItem title="Type d'entité" value="entityType">
|
||||
@@ -97,11 +93,7 @@
|
||||
</MalioAccordionItem>
|
||||
|
||||
<MalioAccordionItem title="Utilisateur / compte" value="username">
|
||||
<MalioSelect
|
||||
v-model="list.draftUsername.value"
|
||||
:options="list.usernameOptions.value"
|
||||
empty-option-label="Tous"
|
||||
/>
|
||||
<MalioInputText v-model="list.draftUsername.value" icon-name="mdi:magnify" />
|
||||
</MalioAccordionItem>
|
||||
|
||||
<MalioAccordionItem title="IP" value="ip">
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { AuditLog } from './dto/audit-log'
|
||||
|
||||
export type AuditLogFilters = {
|
||||
employeeId?: number
|
||||
employee?: string
|
||||
from?: string
|
||||
to?: string
|
||||
entityType?: string[]
|
||||
@@ -24,7 +24,7 @@ export const fetchAuditLogs = async (filters: AuditLogFilters = {}): Promise<Aud
|
||||
const api = useApi()
|
||||
const params: Record<string, string | string[]> = {}
|
||||
|
||||
if (filters.employeeId) params.employeeId = String(filters.employeeId)
|
||||
if (filters.employee && filters.employee.trim() !== '') params.employee = filters.employee.trim()
|
||||
if (filters.from) params.from = filters.from
|
||||
if (filters.to) params.to = filters.to
|
||||
if (filters.entityType && filters.entityType.length > 0) params['entityType[]'] = filters.entityType
|
||||
|
||||
Reference in New Issue
Block a user