setup-user updated #35

Merged
naeem.ullah merged 1 commits from mazdak/UX-1985 into dev-pending-01-01-2026 3 weeks ago

@ -1,95 +0,0 @@
import { Injectable } from '@angular/core';
import { SetupUser } from '../models/user';
import { BehaviorSubject, Observable } from 'rxjs';
import { URIKey } from '../utils/uri-enums';
import { URIService } from '../app.uri';
import { HttpURIService } from '../app.http.uri.service';
import { HttpParams } from '@angular/common/http';
@Injectable({
providedIn: 'root'
})
export class UserSetupService {
private usersSubject = new BehaviorSubject<SetupUser[]>([]);
private currentPageSubject = new BehaviorSubject<number>(1);
private totalCountSubject = new BehaviorSubject<number>(0);
private itemsPerPageSubject = new BehaviorSubject<number>(5);
users$ = this.usersSubject.asObservable();
currentPage$ = this.currentPageSubject.asObservable();
totalCount$ = this.totalCountSubject.asObservable();
itemsPerPage$ = this.itemsPerPageSubject.asObservable();
constructor(private httpURIService: HttpURIService, private uriService: URIService) { }
loadUsers(): void {
this.uriService.canSubscribe.subscribe(can => {
if (can) {
this.httpURIService
.requestGET<any>(URIKey.GET_ALL_USERS)
.subscribe({
next: (res) => {
const users = Array.isArray(res) ? res : res?.data;
this.usersSubject.next(users ?? []);
this.totalCountSubject.next(users.length);
},
error: (err) => console.error(err)
});
}
});
}
setItemsPerPage(itemsPerPage: number): void {
this.itemsPerPageSubject.next(itemsPerPage);
this.currentPageSubject.next(1);
}
nextPage(): void {
const totalPages = this.getTotalPages();
const currentPage = this.currentPageSubject.value;
if (currentPage < totalPages) {
this.currentPageSubject.next(currentPage + 1);
}
}
previousPage(): void {
const currentPage = this.currentPageSubject.value;
if (currentPage > 1) {
this.currentPageSubject.next(currentPage - 1);
}
}
goToPage(page: number): void {
const totalPages = this.getTotalPages();
if (page > 0 && page <= totalPages) {
this.currentPageSubject.next(page);
}
}
getTotalPages(): number {
const totalCount = this.totalCountSubject.value;
const itemsPerPage = this.itemsPerPageSubject.value;
return Math.ceil(totalCount / itemsPerPage);
}
addUser(payload: SetupUser): Observable<SetupUser> {
return this.httpURIService.requestPOST<SetupUser>(URIKey.CREATE_USER, payload);
}
getUserById(userId: any){
const params = new HttpParams().set('userId', userId)
return this.httpURIService.requestGET(URIKey.GET_USER_BY_ID, params);
}
deleteUser(userId: any){
const params = new HttpParams().set('userId', userId)
console.log("params success",params)
return this.httpURIService.requestDELETE(URIKey.DELETE_USER, params)
}
}

@ -163,7 +163,7 @@
<div class="container-fluid"> <div class="container-fluid">
<div class="col-xl-12 mt-4"> <div class="col-xl-12 mt-4">
<div class="card border"> <div class="card border">
<div class="card-body"> <div class="card-body" *ngIf="renewalDataExpanded && allItems.length; else noRecordsFound">
<div class="table-section"> <div class="table-section">
<div class="row"> <div class="row">
<div class="col-lg-12"> <div class="col-lg-12">
@ -175,12 +175,11 @@
<div class="search-box"> <div class="search-box">
<input type="text" class="form-control form-control-sm" <input type="text" class="form-control form-control-sm"
[(ngModel)]="searchText" [(ngModel)]="searchText"
(ngModelChange)="onSearch($event)"
placeholder="{{ 'search' | translate }}"> placeholder="{{ 'search' | translate }}">
<i class="fas fa-search search-icon"></i> <i class="fas fa-search search-icon"></i>
</div> </div>
<i class="materialdesignicons"> <i class="materialdesignicons" (click)="toggleTableCard()">
<ng-container *ngIf="renewalDataExpanded; else collapsedIcon"> <ng-container *ngIf="userSetupDataExpanded; else collapsedIcon">
<i class="dripicons-chevron-up float-end"></i> <i class="dripicons-chevron-up float-end"></i>
</ng-container> </ng-container>
<ng-template #collapsedIcon> <ng-template #collapsedIcon>
@ -189,7 +188,7 @@
</i> </i>
</div> </div>
</div> </div>
<div class="card-body"> <div class="card-body" *ngIf="userSetupDataExpanded && allItems.length; else noRecordsFound">
<div class="table-responsive"> <div class="table-responsive">
<table class="table mb-0 border"> <table class="table mb-0 border">
<thead class="table-light"> <thead class="table-light">
@ -200,30 +199,27 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr *ngFor=" <tr *ngFor="let item of (allItems | tableFilter: searchText : ['userId', 'userFullname']).slice((currentPage-1)*itemsPerPage, currentPage*itemsPerPage)">
let item of (
(users$ | async) ?? []
| userFilter: searchText <td>{{ item.userId }}</td>
).slice((currentPage - 1) * itemsPerPage, currentPage * itemsPerPage) <td>{{ item.userFullname }}</td>
">
<td>{{ item.userId }}</td> <td>
<td>{{ item.userFullname }}</td> <div class="d-flex justify-content-center gap-2">
<button class="btn btn-info btn-sm" title="View" (click)="onView(item.userId)">
<td> <i class="mdi mdi-eye-outline"></i>
<div class="d-flex justify-content-center gap-2"> </button>
<button class="btn btn-info btn-sm" title="View" (click)="onView(item.userId)"> <button *ngIf="buttonPermissions?.delete" class="btn btn-danger btn-sm" title="Delete"
<i class="mdi mdi-eye-outline"></i> (click)="onDelete(item.userId)">
</button> <i class="fas fa-trash-alt"></i>
</button>
<button *ngIf="buttonPermissions?.delete" class="btn btn-danger btn-sm" title="Delete" (click)="onDelete(item.userId)">
<i class="fas fa-trash-alt"></i> </div>
</button> </td>
</div>
</td>
</tr> </tr>
</tbody> </tbody>
@ -235,16 +231,19 @@
bindLabel="label" bindLabel="label"
bindValue="value" bindValue="value"
[(ngModel)]="itemsPerPage" [(ngModel)]="itemsPerPage"
(change)="onPageSizeChange(itemsPerPage)" (change)="itemsPerPageChanged()"
[searchable]="false" [searchable]="false"
[clearable]="false" [clearable]="false"
[dropdownPosition]="'top'"> [dropdownPosition]="'top'">
</ng-select> </ng-select>
</div> </div>
<div class="text-muted"> <div class="text-muted" *ngIf="allItems.length > 1">
{{ 'page' | translate }} {{ currentPage }} {{ 'of' | translate }} {{ getTotalPages() }} ({{ totalCount }} {{ 'totalItems' | translate }}) {{'page' | translate}} {{currentPage}} {{'of' |
</div> translate}} {{totalPages()}} ({{allItems.length}}
{{'totalItems' | translate}})
</div>
<div class="btn-group"> <div class="btn-group">
<button class="btn btn-primary waves-effect waves-light" (click)="previousPage()"> <button class="btn btn-primary waves-effect waves-light" (click)="previousPage()">
@ -269,4 +268,9 @@
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<ng-template #noRecordsFound>
<div *ngIf="!isLoading && allItems.length === 0" class="text-center text-muted mt-3">
<p>{{'noUserDetailsFound' | translate}}</p>
</div>
</ng-template>

@ -5,22 +5,24 @@ import { NgSelectModule } from '@ng-select/ng-select';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
import { pageSizeOptions } from '../../utils/app.constants'; import { pageSizeOptions } from '../../utils/app.constants';
import { SetupUser } from '../../models/user'; import { SetupUser } from '../../models/user';
import { UserSetupService } from '../../services/user-setup.service';
import { UserFilterPipe } from '../../shared/pipes/userFilterPipe';
import { FormBuilder, Validators, FormGroup } from '@angular/forms'; import { FormBuilder, Validators, FormGroup } from '@angular/forms';
import { ButtonManagementService } from '../../services/button-management.service'; import { ButtonManagementService } from '../../services/button-management.service';
import { StorageService } from '../../shared/services/storage.service'; import { StorageService } from '../../shared/services/storage.service';
import { TableFilterPipe } from '../../shared/pipes/table-filter.pipe';
import { URIKey } from '../../utils/uri-enums';
import { HttpParams } from '@angular/common/http';
import { HttpURIService } from '../../app.http.uri.service';
@Component({ @Component({
selector: 'app-setup-user', selector: 'app-setup-user',
standalone: true, standalone: true,
imports: [TranslateModule, ReactiveFormsModule, FormsModule, CommonModule, NgSelectModule, UserFilterPipe], imports: [TranslateModule, ReactiveFormsModule, FormsModule, CommonModule, NgSelectModule, TableFilterPipe],
templateUrl: './setup-user.component.html', templateUrl: './setup-user.component.html',
styleUrl: './setup-user.component.scss' styleUrl: './setup-user.component.scss'
}) })
export class SetupUserComponent implements OnInit { export class SetupUserComponent implements OnInit {
userForm!: FormGroup; userForm!: FormGroup;
showForm = false; showForm = false;
selectedUserId!: any; selectedUserId!: any;
@ -30,11 +32,16 @@ export class SetupUserComponent implements OnInit {
currentPage: number = 1; currentPage: number = 1;
pageSizeOptions = pageSizeOptions pageSizeOptions = pageSizeOptions
itemsPerPage: number = 5; itemsPerPage: number = 5;
searchText: string = ''; pagedItems: any[] = [];
searchText: any = '';
renewalDataExpanded: boolean = true; renewalDataExpanded: boolean = true;
totalCount: number = 0; totalCount: number = 0;
mode: 'edit' | 'view' = 'view'; mode: 'edit' | 'view' = 'view';
userSetupDataExpanded: boolean = true
buttonPermissions: any; buttonPermissions: any;
isLoading: boolean = false;
setupUserList: SetupUser[] = [];
roleOptions = [ roleOptions = [
{ label: 'Admin', value: 'ADMIN' }, { label: 'Admin', value: 'ADMIN' },
{ label: 'User', value: 'USER' } { label: 'User', value: 'USER' }
@ -42,41 +49,41 @@ export class SetupUserComponent implements OnInit {
constructor( constructor(
private userService: UserSetupService,
private fb: FormBuilder, private fb: FormBuilder,
private buttonManagementService: ButtonManagementService, private buttonManagementService: ButtonManagementService,
private storageService: StorageService private storageService: StorageService,
private httpService: HttpURIService
){} ){}
get users$(){
return this.userService.users$;
}
onSearch(value: string): void { onSearch(value: string): void {
this.searchText = value; this.searchText = value;
}
onPageSizeChange(pageSize: number): void {
this.userService.setItemsPerPage(pageSize);
} }
nextPage(): void { totalPages(): number {
this.userService.nextPage(); return Math.ceil(this.allItems.length / this.itemsPerPage);
} }
previousPage(): void { previousPage(): void {
this.userService.previousPage(); if (this.currentPage > 1) {
this.currentPage--;
}
}
nextPage(): void {
if (this.currentPage < this.totalPages()) {
this.currentPage++;
}
} }
getTotalPages(): number { itemsPerPageChanged(): void {
return this.userService.getTotalPages(); this.currentPage = 1;
this.updatePagedItems();
} }
onSubmit() { onSubmit() {
if (this.userForm.invalid) { if (this.userForm.invalid) {
this.userForm.markAllAsTouched(); this.userForm.markAllAsTouched();
return; return;
} }
const newUser : SetupUser = { const newUser : SetupUser = {
userId: this.userForm.value.userId, userId: this.userForm.value.userId,
@ -87,12 +94,11 @@ export class SetupUserComponent implements OnInit {
password: this.userForm.value.defaultPassword password: this.userForm.value.defaultPassword
} }
this.userService.addUser(newUser).subscribe({ this.httpService.requestPOST<SetupUser[]>(URIKey.CREATE_USER, newUser).subscribe({
next: () => { next: () => {
this.userService.loadUsers();
this.userService.loadUsers();
this.userForm.reset(); this.userForm.reset();
this.mode = 'edit'; this.mode = 'edit';
this.loadUsersDirect()
}, },
error: (err: any) => console.error(err) error: (err: any) => console.error(err)
@ -101,33 +107,19 @@ export class SetupUserComponent implements OnInit {
} }
onView(userId: any){ updatePagedItems(): void {
this.mode = 'view'; const startIndex = (this.currentPage - 1) * this.itemsPerPage;
this.showForm = true; const endIndex = startIndex + this.itemsPerPage;
this.selectedUserId = userId; this.pagedItems = this.allItems.slice(startIndex, endIndex);
this.userService.getUserById(userId).subscribe((user: any)=>{ }
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.userForm.reset()
this.selectedUserId = null;
},
error: (err:any) =>{
console.log('user not deleted')
}
});
getButtonPermissions(){
this.buttonPermissions = this.buttonManagementService.buttonPermissions["setupUser"];
} }
toggleTableCard(): void {
this.userSetupDataExpanded = !this.userSetupDataExpanded;
}
ngOnInit(): void { ngOnInit(): void {
@ -140,25 +132,66 @@ ngOnInit(): void {
email: ['', [Validators.required, Validators.email]], email: ['', [Validators.required, Validators.email]],
userRole: [null, Validators.required] userRole: [null, Validators.required]
}); });
this.loadUsersDirect();
this.userService.loadUsers(); }
this.userService.users$.subscribe((users: SetupUser[]) => { loadUsersDirect(): void {
this.allItems = users; this.isLoading = false;
}); let params = new HttpParams()
this.userService.currentPage$.subscribe((page: number) => { .set('page', this.currentPage.toString())
this.currentPage = page; .set('size', this.itemsPerPage.toString());
});
this.userService.totalCount$.subscribe((count: number) => { this.httpService.requestGET<any[]>(URIKey.GET_ALL_USER_URI, params).subscribe({
this.totalCount = count; next: (response) => {
this.setupUserList = response
this.allItems = [...this.setupUserList];
this.updatePagedItems();
this.isLoading = false;
},
error: (err) => {
console.error('Error fetching users:', err);
this.allItems = [];
this.isLoading = false;
}
}); });
this.userService.itemsPerPage$.subscribe((size: number) => { }
this.itemsPerPage = size;
onView(userId: any): void{
let params = new HttpParams().set('userId', userId);
this.httpService.requestGET<SetupUser>(URIKey.GET_USER_BY_ID, params).subscribe({
next: (response: SetupUser) => {
this.userForm.patchValue({
userId: response.userId,
userFullname: response.userFullname,
email: response.email,
userRole: response.role,
defaultPassword: ''
});
this.selectedUserId = userId;
this.isLoading = false;
},
error: (err) => {
console.error('Error fetching users:', err);
this.allItems = [];
this.isLoading = false;
}
}); });
} }
getButtonPermissions(){ onDelete(userId: any){
this.buttonPermissions = this.buttonManagementService.buttonPermissions["setupUser"]; let params = new HttpParams().set('userId', userId);
this.httpService.requestDELETE<any>(URIKey.DELETE_USER, params).subscribe({
next: (response) =>{
this.loadUsersDirect();
this.userForm.reset()
this.selectedUserId = null;
},
error: (err) =>{
console.error('Error fetching users:', err);
this.allItems = [];
this.isLoading = false;
}
})
} }
} }

@ -249,6 +249,7 @@
"allow": "يسمح", "allow": "يسمح",
"toDateInvalidError": "يجب أن يكون تاريخ اليوم أكبر من أو يساوي تاريخ البداية", "toDateInvalidError": "يجب أن يكون تاريخ اليوم أكبر من أو يساوي تاريخ البداية",
"noLoggingDetailsFound": "لم يتم العثور على تفاصيل التسجيل", "noLoggingDetailsFound": "لم يتم العثور على تفاصيل التسجيل",
"noUserDetailsFound": "لم يتم العثور على تفاصيل المستخدم",
"ERR_SEC_0001": "البريد الإلكتروني موجود بالفعل", "ERR_SEC_0001": "البريد الإلكتروني موجود بالفعل",
"ERR_SEC_0002": "اسم المستخدم موجود بالفعل", "ERR_SEC_0002": "اسم المستخدم موجود بالفعل",
"ERR_SEC_0003": "كلمة المرور القديمة غير صحيحة", "ERR_SEC_0003": "كلمة المرور القديمة غير صحيحة",

@ -249,6 +249,7 @@
"allow": "Allow", "allow": "Allow",
"toDateInvalidError": "To Date must be greater than or equal to From Date", "toDateInvalidError": "To Date must be greater than or equal to From Date",
"noLoggingDetailsFound": "No Logging Details found", "noLoggingDetailsFound": "No Logging Details found",
"noUserDetailsFound":"No User Details found",
"ERR_SEC_0001": "Email already exists", "ERR_SEC_0001": "Email already exists",
"ERR_SEC_0002": "Username already exists", "ERR_SEC_0002": "Username already exists",
"ERR_SEC_0003": "Old Password is not correct", "ERR_SEC_0003": "Old Password is not correct",

Loading…
Cancel
Save