You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
aConnect-UX/src/app/menu/menu.component.ts

198 lines
6.9 KiB
TypeScript

import { Component } from '@angular/core';
import { FormBuilder, FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms';
import { PermissionNode } from '../utils/app.interfaces';
import { CredentialService } from '../services/credential.service';
import { I18NService } from '../services/i18n.service';
import { HttpURIService } from '../app.http.uri.service';
import { TranslateModule } from '@ngx-translate/core';
import { URIKey } from '../utils/uri-enums';
import { HttpErrorResponse, HttpParams } from '@angular/common/http';
import { CommonModule } from '@angular/common';
import { NgSelectModule } from '@ng-select/ng-select';
import { filter, Observable, take } from 'rxjs';
import { SuccessMessages } from '../utils/enums';
import { URIService } from '../app.uri';
@Component({
selector: 'app-menu',
imports: [TranslateModule, ReactiveFormsModule, CommonModule, TranslateModule, NgSelectModule, FormsModule],
templateUrl: './menu.component.html',
styleUrl: './menu.component.scss'
})
export class MenuComponent {
users: any[] = [];
permission: FormGroup;
showPermissions = false;
permissions: PermissionNode[] = [];
saving = false;
menuItems: { endpoint: string; checked: boolean }[] = [];
constructor(
private credentialService: CredentialService,
private fb: FormBuilder,
private httpService: HttpURIService,
private i18nService: I18NService,
private uriService: URIService
) {
this.permission = this.fb.group({ userCode: [null] });
this.defaultPermissions().subscribe((data: PermissionNode[]) => {
this.permissions = data; // needed for savePermissions
});
}
ngOnInit() {
this.getAllUsers();
this.loadTransactionEndpoints();
}
loadTransactionEndpoints() {
this.httpService.requestGET<string[]>(URIKey.TRANSACTION_ENDPOINTS).subscribe((response) => {
if (!(response instanceof HttpErrorResponse)) {
this.menuItems = response.map(endpoint => ({
endpoint,
checked: false
}));
}
});
}
defaultPermissions(): Observable<PermissionNode[]> {
return this.httpService.requestGET<PermissionNode[]>('assets/data/sideMenu.json');
}
getAllUsers() {
this.httpService.requestGET<any[]>(URIKey.GET_ALL_USER_URI).subscribe((response) => {
if (!(response instanceof HttpErrorResponse)) {
this.users = response.map(item => ({
userName: item.userFullname,
userId: item.userId,
}));
}
});
}
// mapEndpointsToPermissions(endpoints: string[]): PermissionNode[] {
// return [{
// name: 'menu',
// checked: false,
// expanded: false,
// children: [
// { name: 'accountToAccount', checked: endpoints.includes(this.uriService.getURIForRequest(URIKey.ACCOUNT_TO_ACCOUNT)), expanded: false },
// { name: 'glToGl', checked: endpoints.includes(this.uriService.getURIForRequest(URIKey.GL_TO_GL)), expanded: false },
// { name: 'accountToGl', checked: endpoints.includes(this.uriService.getURIForRequest(URIKey.ACCOUNT_TO_GL)), expanded: false },
// { name: 'glToAccount', checked: endpoints.includes(this.uriService.getURIForRequest(URIKey.GL_TO_ACCOUNT)), expanded: false }
// ]
// }];
// }
onUserChange() {
this.showPermissions = true;
const userId = this.permission.get('userCode')?.value;
const params = new HttpParams().set('userId', userId);
this.httpService.requestGET(URIKey.TRANSACTION_PERMISSIONS, params)
.subscribe((response: any) => {
if (!(response instanceof HttpErrorResponse)) {
const allowedEndpoints: string[] = (response as any[])
.filter(p => p.allowed)
.map(p => this.normalizeUrl(p.transactionEndpoint)); // ← normalize
this.menuItems.forEach(item => {
item.checked = allowedEndpoints.some(allowed =>
allowed.endsWith(this.normalizeUrl(item.endpoint))
);
});
} else {
this.menuItems.forEach(item => item.checked = false);
}
});
}
// Add this helper method to the class
private normalizeUrl(url: string): string {
return url?.trim().toLowerCase().replace(/\/+$/, ''); // trim, lowercase, remove trailing slash
}
// savePermissions() {
// const selectedUser = this.permission.get('userCode')?.value;
// const menuNode = this.permissions.find(x => x.name === 'menu');
// if (!menuNode) return;
// const nameToURIKey: { [key: string]: URIKey } = {
// accountToAccount: URIKey.ACCOUNT_TO_ACCOUNT,
// glToGl: URIKey.GL_TO_GL,
// accountToGl: URIKey.ACCOUNT_TO_GL,
// glToAccount: URIKey.GL_TO_ACCOUNT
// };
// const transactionEndpoints: string[] = (menuNode.children || [])
// .filter(c => c.checked)
// .map(c => this.uriService.getURIForRequest(nameToURIKey[c.name]));
// const payload = { userId: selectedUser, transactionEndpoints, permissions: JSON.stringify(this.permissions) };
// this.httpService.requestPOST(URIKey.TRANSACTION_PERMISSIONS_ASSIGN, payload).subscribe((response: any) => {
// if (!(response instanceof HttpErrorResponse)) {
// this.i18nService.success(SuccessMessages.SAVED_SUCCESSFULLY, []);
// this.permission.get('userCode')?.setValue(selectedUser);
// this.onUserChange();
// }
// });
// }
savePermissions() {
if (this.saving) return; // ← guard against double clicks
this.saving = true;
const selectedUser = this.permission.get('userCode')?.value;
this.uriService.canSubscribe.pipe(
filter(ready => ready === true),
take(1)
).subscribe(() => {
const transactionEndpoints: string[] = this.menuItems
.filter(item => item.checked)
.map(item => item.endpoint);
const payload = { userId: selectedUser, transactionEndpoints };
this.httpService.requestPOST(URIKey.TRANSACTION_PERMISSIONS_ASSIGN, payload)
.subscribe({
next: (response: any) => {
if (!(response instanceof HttpErrorResponse)) {
this.i18nService.success(SuccessMessages.SAVED_SUCCESSFULLY, []);
this.onUserChange(); // this triggers one GET — expected
}
},
complete: () => {
this.saving = false; // ← reset after done
},
error: () => {
this.saving = false;
}
});
});
}
updatePermissions(savedPermissions: PermissionNode[], existingPermissions: PermissionNode[]): void {
for (const existingNode of existingPermissions) {
const savedNode = savedPermissions.find(node => node.name === existingNode.name);
if (savedNode) {
// Update state from saved node
existingNode.checked = savedNode.checked;
//existingNode.expanded = savedNode.expanded;
// Recursively update children if they exist
if (existingNode.children) {
this.updatePermissions(savedNode.children || [], existingNode.children);
}
if (existingNode.buttons) {
this.updatePermissions(savedNode.buttons || [], existingNode.buttons);
}
}
}
}
}