/** * Copyright since 2025 Mifos Initiative * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /** Angular Imports */ import { Component, OnInit, inject } from '@angular/core'; import { ActivatedRoute, Router, RouterLink } from '@angular/router'; import { UntypedFormGroup, UntypedFormBuilder, Validators, ReactiveFormsModule } from '@angular/forms'; import { MatDialog } from '@angular/material/dialog'; /** Custom Services */ import { UsersService } from '../users.service'; import { MatCheckbox } from '@angular/material/checkbox'; import { MatIcon } from '@angular/material/icon'; import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module'; import { SuccessDialogComponent } from 'app/shared/success-dialog/success-dialog.component'; import { ErrorDialogComponent } from 'app/shared/error-dialog/error-dialog.component'; /** * Edit User Component. */ @Component({ selector: 'mifosx-edit-user', templateUrl: './edit-user.component.html', styleUrls: ['./edit-user.component.scss'], imports: [ ...STANDALONE_SHARED_IMPORTS, MatCheckbox, MatIcon ] }) export class EditUserComponent implements OnInit { private formBuilder = inject(UntypedFormBuilder); private usersService = inject(UsersService); private route = inject(ActivatedRoute); private router = inject(Router); private dialog = inject(MatDialog); /** User Data */ userData: any; /** Offices Data */ officesData: any; /** Staff Data */ staffData: any; /** Roles Data */ rolesData: any; /** Edit User form. */ editUserForm: UntypedFormGroup; /** * Retrieves the offices data from `resolve`. * @param {FormBuilder} formBuilder Form Builder. * @param {UsersService} UsersService Users Service. * @param {ActivatedRoute} route Activated Route. * @param {Router} router Router for navigation. */ constructor() { this.route.data.subscribe((data: { user: any; usersTemplate: any }) => { this.userData = data.user; this.officesData = data.usersTemplate.allowedOffices; this.rolesData = data.usersTemplate.availableRoles; }); } ngOnInit() { this.createEditUserForm(); this.officeChanged(this.userData.officeId); } /** * Creates the edit user form. */ createEditUserForm() { const staffId = this.userData.staff ? this.userData.staff.id : null; this.editUserForm = this.formBuilder.group({ username: [ this.userData.username, Validators.required ], email: [ this.userData.email, [ Validators.required, Validators.email, Validators.pattern(/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/) ] ], mobileNo: [ this.userData.mobileNo || '', [ Validators.required, Validators.pattern(/^\d{10}$/) ] ], firstname: [ this.userData.firstname, [ Validators.required, Validators.pattern('(^[A-z]).*') ] ], lastname: [ this.userData.lastname, [ Validators.required, Validators.pattern('(^[A-z]).*') ] ], passwordNeverExpires: [this.userData.passwordNeverExpires], officeId: [ this.userData.officeId, Validators.required ], staffId: [staffId], roles: [ this.userData.selectedRoles.map((role: any) => role.id), Validators.required ] }); } /** * Fetches the staff for the selected office * @param officeId the selected office id */ officeChanged(officeId: number) { this.staffData = []; this.usersService.getStaff(officeId).subscribe((staff: any) => { this.staffData = staff; }); } /** * Submits the user form and edits the user, * if successful redirects to the updated user. */ submit() { const editedUser = this.editUserForm.value; this.usersService.editUser(this.userData.id, editedUser).subscribe({ next: (response: any) => { // Fineract sometimes omits resourceId in PUT responses — fall back to // the user id we're editing so navigation never silently no-ops. const targetId = response?.resourceId ?? this.userData.id; const dialogRef = this.dialog.open(SuccessDialogComponent, { data: { title: 'User updated', message: `Changes to ${this.userData.username} have been saved successfully.`, buttonLabel: 'View user' }, panelClass: 'sd-panel', disableClose: true }); dialogRef.afterClosed().subscribe(() => { this.router.navigate( [ '../../', targetId ], { relativeTo: this.route } ); }); }, error: (err) => { console.error('[EditUser] update failed', err); this.dialog.open(ErrorDialogComponent, { data: err?.error?.defaultUserMessage || err?.error?.message || 'Failed to update user.' }); } }); } }