import { Component, computed, inject, linkedSignal, input, afterNextRender } from '@angular/core'; import { form, FormField } from '@angular/forms/signals'; import { MatButtonModule } from '@angular/material/button'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatDialog } from '@angular/material/dialog'; import { MatDividerModule } from '@angular/material/divider'; import { MatFormFieldModule } from '@angular/material/form-field'; import { MatIconModule } from '@angular/material/icon'; import { MatInputModule } from '@angular/material/input'; import { MatSnackBar } from '@angular/material/snack-bar'; import { ActivatedRoute, Router } from '@angular/router'; import { User } from '../../core/user'; import { ConfirmDialogComponent } from '../../shared/confirm-dialog/confirm-dialog.component'; import { UserService } from '../user.service'; export interface UserDetailFormData { name: string; password: string; lockedOut: boolean; roles: { id: string; name: string; enabled: boolean }[]; } @Component({ selector: 'app-user-detail', templateUrl: './user-detail.component.html', styleUrls: ['./user-detail.component.css'], imports: [ MatButtonModule, MatCheckboxModule, MatDividerModule, MatFormFieldModule, MatIconModule, MatInputModule, FormField, ], }) export class UserDetailComponent { private route = inject(ActivatedRoute); private router = inject(Router); private snackBar = inject(MatSnackBar); private dialog = inject(MatDialog); private ser = inject(UserService); id = input(null, { transform: (v: string | null | undefined) => v ?? null }); itemResource = this.ser.get(this.id); item = computed(() => this.itemResource.value() ?? new User()); formModel = linkedSignal({ source: this.item, computation: (itemVal): UserDetailFormData => { return { name: itemVal.name ?? '', password: '', lockedOut: itemVal.lockedOut, roles: itemVal.roles.map((x) => ({ id: x.id ?? '', name: x.name, enabled: x.enabled })), }; }, }); form = form(this.formModel); hide = true; constructor() { afterNextRender(() => { this.form().focusBoundControl(); // this.formModel().root.focus("name"); }); } save() { this.ser.saveOrUpdate(this.getItem()).subscribe({ next: () => { this.snackBar.open('', 'Success'); if ((this.item().id as string) === 'me') { this.router.navigateByUrl('/'); } else { this.router.navigateByUrl('/users'); } }, error: (error: unknown) => { this.snackBar.open(error as string, 'Error'); }, }); } delete() { this.ser.delete(this.item().id as string).subscribe({ next: () => { this.snackBar.open('', 'Success'); this.router.navigateByUrl('/users'); }, error: (error: unknown) => { this.snackBar.open(error as string, 'Error'); }, }); } confirmDelete(): void { const dialogRef = this.dialog.open(ConfirmDialogComponent, { width: '250px', data: { title: 'Delete User?', content: 'Are you sure? This cannot be undone.' }, }); dialogRef.afterClosed().subscribe((result: boolean) => { if (result) { this.delete(); } }); } getItem(): User { const formModel = this.formModel(); return new User({ ...this.item(), name: formModel.name ?? '', password: formModel.password ?? '', lockedOut: formModel.lockedOut ?? true, roles: formModel.roles.map((x) => ({ id: x.id ?? '', name: x.name, enabled: x.enabled })), }); } }