From 35c23badcccc451120c912e97d5480cd3c338c36 Mon Sep 17 00:00:00 2001 From: Mazdak Gibran <141390141+mazdakgibran@users.noreply.github.com> Date: Thu, 1 Jan 2026 15:40:42 +0500 Subject: [PATCH 1/3] updated the form with Reactive Forms updated the form with Reactive Forms --- src/app/services/user-setup.service.ts | 39 +-------- src/app/shared/pipes/userFilterPipe.ts | 22 +++++ .../setup-user/setup-user.component.html | 49 ++++++----- .../setup-user/setup-user.component.ts | 86 ++++++++++--------- src/assets/i18n/Arabic.json | 1 + src/assets/i18n/English.json | 1 + 6 files changed, 101 insertions(+), 97 deletions(-) create mode 100644 src/app/shared/pipes/userFilterPipe.ts diff --git a/src/app/services/user-setup.service.ts b/src/app/services/user-setup.service.ts index b26f4c2..3ee7018 100644 --- a/src/app/services/user-setup.service.ts +++ b/src/app/services/user-setup.service.ts @@ -13,15 +13,11 @@ export class UserSetupService { private usersSubject = new BehaviorSubject([]); private currentPageSubject = new BehaviorSubject(1); private totalCountSubject = new BehaviorSubject(0); - private searchTextSubject = new BehaviorSubject(''); private itemsPerPageSubject = new BehaviorSubject(5); - private paginatedUsersSubject = new BehaviorSubject([]); users$ = this.usersSubject.asObservable(); currentPage$ = this.currentPageSubject.asObservable(); totalCount$ = this.totalCountSubject.asObservable(); - searchText$ = this.searchTextSubject.asObservable(); itemsPerPage$ = this.itemsPerPageSubject.asObservable(); - paginatedUsers$ = this.paginatedUsersSubject.asObservable(); constructor(private httpURIService: HttpURIService, private uriService: URIService) { } @@ -35,7 +31,7 @@ loadUsers(): void { const users = Array.isArray(res) ? res : res?.data; this.usersSubject.next(users ?? []); this.totalCountSubject.next(users.length); - this.applyPagination(); + }, error: (err) => console.error(err) }); @@ -43,36 +39,10 @@ loadUsers(): void { }); } - private applyPagination(): void { - const allUsers = this.usersSubject.value; - const searchText = this.searchTextSubject.value.toLowerCase(); - const currentPage = this.currentPageSubject.value; - const itemsPerPage = this.itemsPerPageSubject.value; - - let filtered = allUsers.filter(user => - user.userId.toLowerCase().includes(searchText) || - user.userFullname.toLowerCase().includes(searchText) || - user.email.toLowerCase().includes(searchText) - ); - - const totalCount = filtered.length; - const startIndex = (currentPage - 1) * itemsPerPage; - const paginatedUsers = filtered.slice(startIndex, startIndex + itemsPerPage); - - this.paginatedUsersSubject.next(paginatedUsers); - this.totalCountSubject.next(totalCount); - } - - setSearchText(searchText: string): void { - this.searchTextSubject.next(searchText); - this.currentPageSubject.next(1); - this.applyPagination(); - } - setItemsPerPage(itemsPerPage: number): void { this.itemsPerPageSubject.next(itemsPerPage); this.currentPageSubject.next(1); - this.applyPagination(); + } nextPage(): void { @@ -80,7 +50,6 @@ loadUsers(): void { const currentPage = this.currentPageSubject.value; if (currentPage < totalPages) { this.currentPageSubject.next(currentPage + 1); - this.applyPagination(); } } @@ -88,7 +57,7 @@ loadUsers(): void { const currentPage = this.currentPageSubject.value; if (currentPage > 1) { this.currentPageSubject.next(currentPage - 1); - this.applyPagination(); + } } @@ -96,7 +65,7 @@ loadUsers(): void { const totalPages = this.getTotalPages(); if (page > 0 && page <= totalPages) { this.currentPageSubject.next(page); - this.applyPagination(); + } } diff --git a/src/app/shared/pipes/userFilterPipe.ts b/src/app/shared/pipes/userFilterPipe.ts new file mode 100644 index 0000000..7bb23cd --- /dev/null +++ b/src/app/shared/pipes/userFilterPipe.ts @@ -0,0 +1,22 @@ +import { Pipe, PipeTransform } from '@angular/core'; +import { SetupUser } from '../../models/user'; + +@Pipe({ + name: 'userFilter', + standalone: true +}) +export class UserFilterPipe implements PipeTransform { + transform(users: SetupUser[], searchText: string): SetupUser[] { + if (!users || !searchText.trim()) { + return users; + } + + const search = searchText.toLowerCase(); + + return users.filter(user => + user.userId.toLowerCase().includes(search) || + user.userFullname.toLowerCase().includes(search) || + user.email.toLowerCase().includes(search) + ); + } +} \ No newline at end of file diff --git a/src/app/user-management/setup-user/setup-user.component.html b/src/app/user-management/setup-user/setup-user.component.html index b8a681c..2f60c9d 100644 --- a/src/app/user-management/setup-user/setup-user.component.html +++ b/src/app/user-management/setup-user/setup-user.component.html @@ -22,7 +22,7 @@ {{'setupUser' | translate}}
-
+
@@ -34,15 +34,15 @@
- -
- +
+ +
+ {{ 'requiredField' | translate }} +
@@ -57,7 +57,7 @@ +
+ {{ 'requiredField' | translate }}
@@ -80,18 +83,14 @@
- + +
+
+ {{ 'requiredField' | translate }}
@@ -101,8 +100,8 @@
- @@ -137,7 +136,7 @@ @@ -162,7 +161,13 @@ - + + {{ item.userId }} {{ item.userFullname }} @@ -177,9 +182,11 @@ +
+
diff --git a/src/app/user-management/setup-user/setup-user.component.ts b/src/app/user-management/setup-user/setup-user.component.ts index 5ffa79f..01b3097 100644 --- a/src/app/user-management/setup-user/setup-user.component.ts +++ b/src/app/user-management/setup-user/setup-user.component.ts @@ -6,16 +6,24 @@ import { TranslateModule } from '@ngx-translate/core'; import { pageSizeOptions } from '../../utils/app.constants'; import { SetupUser } from '../../models/user'; import { UserSetupService } from '../../services/user-setup.service'; -import { error } from 'node:console'; +import { UserFilterPipe } from '../../shared/pipes/userFilterPipe'; +import { FormBuilder, Validators, FormGroup } from '@angular/forms'; + @Component({ selector: 'app-setup-user', standalone: true, - imports: [TranslateModule, ReactiveFormsModule, FormsModule, CommonModule, NgSelectModule], + imports: [TranslateModule, ReactiveFormsModule, FormsModule, CommonModule, NgSelectModule, UserFilterPipe], templateUrl: './setup-user.component.html', styleUrl: './setup-user.component.scss' }) export class SetupUserComponent implements OnInit { + + userForm!: FormGroup; + showForm = false; + selectedUserId!: any; + showDeleteModal = false; + userIdToDelete: any = null; allItems: SetupUser[] = []; currentPage: number = 1; pageSizeOptions = pageSizeOptions @@ -23,18 +31,16 @@ export class SetupUserComponent implements OnInit { searchText: string = ''; renewalDataExpanded: boolean = true; totalCount: number = 0; - userId!: string; - userFullname!: string; - defaultPassword!: string; mode: 'edit' | 'view' = 'view'; - showForm = false; - selectedUserId!: any; - user: any; - constructor(private userService: UserSetupService){} + constructor(private userService: UserSetupService, private fb: FormBuilder){} + + get users$(){ + return this.userService.users$; + } onSearch(value: string): void { - this.userService.setSearchText(value); + this.searchText = value; } onPageSizeChange(pageSize: number): void { @@ -48,36 +54,30 @@ export class SetupUserComponent implements OnInit { previousPage(): void { this.userService.previousPage(); } - - totalPages() { - return 1; - } - toggleCard(arg0: string) { - throw new Error('Method not implemented.'); - } + getTotalPages(): number { return this.userService.getTotalPages(); } onSubmit() { - if(!this.userId || !this.userFullname|| !this.defaultPassword){ - console.warn('Form incomplete'); - return - } + if (this.userForm.invalid) { + this.userForm.markAllAsTouched(); + return; +} const newUser : SetupUser = { - userId: this.userId, - userFullname: this.userFullname, - email: `${this.userId}@dummy.com` ,// temporary placeholder + userId: this.userForm.value.userId, + userFullname: this.userForm.value.userFullname, + email: `${this.userForm.value.userId}@dummy.com`, role: 'ADMIN', - defaultPassword: this.defaultPassword + defaultPassword: this.userForm.value.defaultPassword } this.userService.addUser(newUser).subscribe({ next: () => { this.userService.loadUsers(); - this.userId = ''; - this.userFullname = ''; - this.defaultPassword = ''; + this.userService.loadUsers(); + this.userForm.reset(); + this.mode = 'edit'; }, error: (err: any) => console.error(err) }); @@ -90,21 +90,20 @@ export class SetupUserComponent implements OnInit { this.showForm = true; this.selectedUserId = userId; this.userService.getUserById(userId).subscribe((user: any)=>{ - this.userId = user.userId; - this.userFullname = user.userFullname; - this.defaultPassword = ''; + this.userForm.patchValue({ + userId : user.userId, + userFullname : user.userFullname, + defaultPassword : '', + }) }) } onDelete(userId: any){ this.userService.deleteUser(userId).subscribe({ next: (res: any) => { - this.userService.loadUsers(); - this.showForm = false; - this.userId = ''; - this.userFullname = ''; - this.defaultPassword = ''; - this.selectedUserId = null; + this.userService.loadUsers(); + this.userForm.reset() + this.selectedUserId = null; }, error: (err:any) =>{ console.log('user not deleted') @@ -115,18 +114,23 @@ export class SetupUserComponent implements OnInit { } ngOnInit(): void { + this.userForm = this.fb.group({ + userId: ['', [Validators.required]], + userFullname: ['', [Validators.required, Validators.maxLength(500)]], + defaultPassword: ['', Validators.required] + }); + this.userService.loadUsers(); - this.userService.paginatedUsers$.subscribe((users: SetupUser[]) => this.allItems = users); + this.userService.users$.subscribe((users: SetupUser[]) => { + this.allItems = users; + }); this.userService.currentPage$.subscribe((page: number) => { this.currentPage = page; }); this.userService.totalCount$.subscribe((count: number) => { this.totalCount = count; }); - this.userService.searchText$.subscribe((text: string) => { - this.searchText = text; - }); this.userService.itemsPerPage$.subscribe((size: number) => { this.itemsPerPage = size; }); diff --git a/src/assets/i18n/Arabic.json b/src/assets/i18n/Arabic.json index 397f143..2cc2571 100644 --- a/src/assets/i18n/Arabic.json +++ b/src/assets/i18n/Arabic.json @@ -225,6 +225,7 @@ "UNAUTHORIZED_REQUEST": "طلب غير مصرح به", "edit": "يحرر", "delete": "يمسح", + "deleteUser": "حذف حساب المستخدم", "permissionManagement": "إدارة الأذونات", "userCode": "مستخدم", "choose" : "يختار" diff --git a/src/assets/i18n/English.json b/src/assets/i18n/English.json index 6434080..a8574d8 100644 --- a/src/assets/i18n/English.json +++ b/src/assets/i18n/English.json @@ -224,6 +224,7 @@ "UNAUTHORIZED_REQUEST": "Unauthorized Request", "edit": "Edit", "delete": "Delete", + "deleteUser": "Delete User", "permissionManagement": "Permission Managment", "userCode": "User", "choose" : "Choose" From 25d1e49475c80a816f6cd71d10cbd16217e4a9cc Mon Sep 17 00:00:00 2001 From: Mazdak Gibran <141390141+mazdakgibran@users.noreply.github.com> Date: Thu, 1 Jan 2026 15:46:34 +0500 Subject: [PATCH 2/3] add missing translation add missing translation --- .../setup-user/setup-user.component.html | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/app/user-management/setup-user/setup-user.component.html b/src/app/user-management/setup-user/setup-user.component.html index 2f60c9d..f8a8a14 100644 --- a/src/app/user-management/setup-user/setup-user.component.html +++ b/src/app/user-management/setup-user/setup-user.component.html @@ -41,7 +41,7 @@
- {{ 'requiredField' | translate }} + {{ 'fieldRequired' | translate }}
@@ -64,11 +64,11 @@ rows="3" /> - - -
- {{ 'requiredField' | translate }} +
+ {{ 'fieldRequired' | translate }} +
+ @@ -87,11 +87,11 @@ name="defaultPassword" placeholder="{{ 'passwordPlaceHolder' | translate }}" appNoWhitespaces/> - -
- {{ 'requiredField' | translate }} + {{ 'fieldRequired' | translate }}
+ +
From 7ba6a8b65f30065058ea42fec7682343a3ee2b6c Mon Sep 17 00:00:00 2001 From: atif118-mfsys Date: Fri, 2 Jan 2026 10:29:56 +0500 Subject: [PATCH 3/3] integrated the API to save permissions for a specific user --- .../user-permissions.component.ts | 23 ++++++++++--------- src/assets/data/app.uri.json | 5 ++++ 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/app/user-permissions/user-permissions.component.ts b/src/app/user-permissions/user-permissions.component.ts index 1bd2ed8..025ae98 100644 --- a/src/app/user-permissions/user-permissions.component.ts +++ b/src/app/user-permissions/user-permissions.component.ts @@ -130,8 +130,8 @@ export class UserPermissionsComponent { const params = new HttpParams().set('userId', this.permission.get('userCode')?.value); this.httpService.requestGET(URIKey.USER_GET_PERMISSIONS, params).subscribe((response: any) => { if (!(response instanceof HttpErrorResponse)) { - if (response.permission) { - this.updatePermissions(JSON.parse(response.permission), this.permissions); + if (response.permissions) { + this.updatePermissions(JSON.parse(response.permissions), this.permissions); } else { this.defaultPermissions().subscribe((data: PermissionNode[]) => { @@ -144,17 +144,18 @@ export class UserPermissionsComponent { savePermissions() { let payload = { - porOrgacode: this.credentialService.getPorOrgacode(), + // porOrgacode: this.credentialService.getPorOrgacode(), userId: this.permission.get('userCode')?.value, - permission: JSON.stringify(this.permissions) + permissions: JSON.stringify(this.permissions) } - // this.httpService.requestPATCH(URIKey.USER_SAVE_PERMISSION, payload).subscribe((response: any) => { - // if (!(response instanceof HttpErrorResponse)) { - // this.i18nService.success(SuccessMessages.SAVED_SUCESSFULLY, []); - // this.permission.reset(); - // this.showPermissions = false; - // } - // }) + this.httpService.requestPUT(URIKey.USER_SAVE_PERMISSION, payload).subscribe((response: any) => { + if (!(response instanceof HttpErrorResponse)) { + this.i18nService.success(SuccessMessages.SAVED_SUCESSFULLY, []); + this.permission.reset(); + this.permission.get('userCode')?.setValue(""); + this.showPermissions = false; + } + }) } updatePermissions(savedPermissions: PermissionNode[], existingPermissions: PermissionNode[]): void { diff --git a/src/assets/data/app.uri.json b/src/assets/data/app.uri.json index 65e93ab..be0b396 100644 --- a/src/assets/data/app.uri.json +++ b/src/assets/data/app.uri.json @@ -46,6 +46,11 @@ "Id" : "ENTITY_USER_GET_PERMISSIONS", "URI": "/user/getPermissions", "UUID": "USER_GET_PERMISSIONS" + }, + { + "Id" : "ENTITY_USER_SAVE_PERMISSION", + "URI": "/user/updatePermissions", + "UUID": "USER_SAVE_PERMISSION" } ] }