import { CommonModule } from '@angular/common'; import { ChangeDetectionStrategy, Component, ViewChild, signal, effect, untracked, } from '@angular/core'; import { DataTable, TableColumn, SortState } from '@shared/components/data-table/data-table'; import { Paginator } from '@shared/components/paginator/paginator'; import { SearchBar } from '@shared/components/search-bar/search-bar'; import { Modal } from '@shared/components/modal/modal'; import { ZardButtonComponent } from '@shared/components/button/button.component'; import { SortDir } from '@shared/paging/paging'; import { User } from 'src/app/core/interfaces/user'; import { UserService } from 'src/app/core/services/user'; import { Role } from 'src/app/core/interfaces/role'; import { RoleService } from 'src/app/core/services/role'; import { UserForm } from '@shared/forms/user-form/user-form'; import { toast } from 'ngx-sonner'; @Component({ standalone: true, selector: 'app-users', templateUrl: './users.html', changeDetection: ChangeDetectionStrategy.OnPush, imports: [CommonModule, DataTable, Paginator, SearchBar, Modal, ZardButtonComponent, UserForm], }) export class UsersPage { rows = signal([]); total = signal(0); loading = signal(false); roleMap = new Map(); page = signal(1); perPage = signal(10); search = signal(''); sort = signal({ key: 'nom', dir: 'asc' }); modalOpen = signal(false); modalTitle = signal('Nouvel utilisateur'); editingItem = signal(null); @ViewChild(UserForm) formComp?: UserForm; cols: TableColumn[] = [ { key: 'nom', label: 'Nom', sortable: true }, { key: 'prenom', label: 'Prénom', sortable: true }, { key: 'identifiant', label: 'Identifiant', sortable: true }, { key: 'matriculeAgent', label: 'Matricule', sortable: true }, { key: 'role.name', label: 'Rôle', sortable: true, cell: (u) => this.roleMap.get(u.roleId) ?? u.role?.name ?? '—', }, { key: 'statut', label: 'Statut', sortable: true }, { key: 'derniereConnexion', label: 'Dernière connexion', cell: (u) => u.derniereConnexion ? new Date(u.derniereConnexion).toLocaleDateString('fr-FR') : '—', }, { key: 'restrictionConnexion', label: 'Restr. Conn.', cell: (u) => String(u.restrictionConnexion), }, { key: 'restrictionAutomatique', label: 'Restr. Auto', cell: (u) => String(u.restrictionAutomatique), }, { key: 'nombreIpAutorise', label: 'IP Autorisé' }, { key: 'nombreIpAutoAutorise', label: 'IP Auto' }, ]; constructor(private api: UserService, private roleService: RoleService) { this.roleService .list({ page: 1, perPage: 100, search: '', sortKey: 'name', sortDir: 'asc' } as any) .subscribe((res) => (res.data as Role[]).forEach((r) => this.roleMap.set(r.id, r.name))); effect(() => { const params = { page: this.page(), perPage: this.perPage(), search: this.search(), sortKey: this.sort().key, sortDir: this.sort().dir as SortDir, }; untracked(() => this.fetch(params)); }); } private fetch(params: { page: number; perPage: number; search: string; sortKey: string; sortDir: SortDir; }) { this.loading.set(true); this.api.list(params).subscribe({ next: (res) => { this.rows.set(res.data); this.total.set(res.meta.total); this.loading.set(false); }, error: () => { this.rows.set([]); this.total.set(0); this.loading.set(false); }, }); } onSearch(q: string) { this.search.set(q); this.page.set(1); } openCreate() { this.modalTitle.set('Nouvel utilisateur'); this.editingItem.set(null); queueMicrotask(() => this.modalOpen.set(true)); } openEdit(row: User) { this.modalTitle.set("Modifier l'utilisateur"); this.editingItem.set(row); queueMicrotask(() => this.modalOpen.set(true)); } closeModal() { this.modalOpen.set(false); } submitChildForm() { this.formComp?.onSubmit(); } onFormSave(payload: Partial) { const current = this.editingItem(); const req$ = current?.id ? this.api.update(current.id, payload) : this.api.create(payload as Omit); req$.subscribe({ next: (user) => { this.closeModal(); toast.success( current?.id ? `L'utilisateur « ${user?.nom ?? ''} ${ user?.prenom ?? '' } » a été mis à jour avec succès` : `L'utilisateur « ${user?.nom ?? ''} ${user?.prenom ?? ''} » a été créé avec succès` ); this.fetch({ page: this.page(), perPage: this.perPage(), search: this.search(), sortKey: this.sort().key, sortDir: this.sort().dir as SortDir, }); }, error: () => { toast.error( current?.id ? "Erreur lors de la mise à jour de l'utilisateur" : "Erreur lors de la création de l'utilisateur", { duration: 5000 } ); }, }); } remove(row: User) { if (!confirm(`Supprimer l\'utilisateur « ${row.nom} ${row.prenom} » ?`)) return; this.api.delete(row.id).subscribe({ next: (ok) => { if (ok) { toast.success(`L'utilisateur « ${row.nom} ${row.prenom} » a été supprimé avec succès`); this.fetch({ page: this.page(), perPage: this.perPage(), search: this.search(), sortKey: this.sort().key, sortDir: this.sort().dir as SortDir, }); } else { toast.error("Erreur lors de la suppression de l'utilisateur", { duration: 5000 }); } }, error: () => { toast.error("Erreur lors de la suppression de l'utilisateur", { duration: 5000 }); }, }); } }