feat: Client & CKYC UI improvements — filters, KYC management, image crop+merge

- Clients list: CKYC icon, CKYC Number column, status/legal form/CKYC filters
- CKYC: SFTP upload logs, date formatting, modal z-index fix, non-dismissible dialogs
- KYC Management: new standalone module with alert dashboard, notification scheduler, audit inventory, account status
- Image cropper: ngx-image-cropper integration for front+back document merge into single PNG
- Sidebar: KYC Management menu entry after CKYC

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Aditya
2026-04-16 13:51:11 +05:30
co-authored by Claude Opus 4.6
parent 79e455c4ed
commit d72e969dc3
210 changed files with 14273 additions and 1139 deletions
+42 -9
View File
@@ -8,7 +8,6 @@
/** Angular Imports. */
import { Component, OnInit, ViewChild, inject } from '@angular/core';
import { MatCheckbox } from '@angular/material/checkbox';
import { MatPaginator, PageEvent } from '@angular/material/paginator';
import { MatSort, Sort, MatSortHeader } from '@angular/material/sort';
import {
@@ -46,7 +45,6 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
styleUrls: ['./clients.component.scss'],
imports: [
...STANDALONE_SHARED_IMPORTS,
MatCheckbox,
FaIconComponent,
MatProgressBar,
MatTable,
@@ -88,12 +86,11 @@ export class ClientsComponent implements OnInit {
.join(' ');
}
@ViewChild('showClosedAccounts') showClosedAccounts: MatCheckbox;
displayedColumns = [
'displayName',
'accountNumber',
'cifNumber',
'ckycNumber',
'legalForm',
'status',
'profileCompletion',
@@ -115,6 +112,12 @@ export class ClientsComponent implements OnInit {
sortAttribute = '';
sortDirection = '';
statusFilter = '';
legalFormFilter = '';
ckycFilter = '';
private allRows: any[] = [];
@ViewChild(MatPaginator) paginator: MatPaginator;
@ViewChild(MatSort) sort: MatSort;
@@ -139,14 +142,16 @@ export class ClientsComponent implements OnInit {
.searchByText(this.filterText, this.currentPage, this.pageSize, this.sortAttribute, this.sortDirection)
.subscribe(
(data: any) => {
this.dataSource.data = data.content;
this.allRows = data.content || [];
this.totalRows = data.totalElements;
this.existsClientsToFilter = data.numberOfElements > 0;
this.notExistsClientsToFilter = !this.existsClientsToFilter;
this.isLoading = false;
this.applyClientFilters();
// Fetch KYC & address status for visible rows
this.loadProfileStatus(data.content);
this.loadProfileStatus(this.allRows);
},
(error: any) => {
this.isLoading = false;
@@ -167,7 +172,7 @@ export class ClientsComponent implements OnInit {
).subscribe((data: any) => {
if (data?.legalForm) {
clients[i].legalForm = data.legalForm;
this.dataSource.data = [...clients];
this.applyClientFilters();
}
});
@@ -176,7 +181,9 @@ export class ClientsComponent implements OnInit {
).subscribe((kyc: any) => {
if (kyc) {
clients[i]._kycDone = kyc.kycStatus === 300;
this.dataSource.data = [...clients];
clients[i]._ckycDone = !!kyc.ckycNumber;
clients[i]._ckycNumber = kyc.ckycNumber || '';
this.applyClientFilters();
}
});
@@ -185,12 +192,38 @@ export class ClientsComponent implements OnInit {
).subscribe((addr: any) => {
if (addr && Array.isArray(addr) && addr.length > 0) {
clients[i]._addressDone = true;
this.dataSource.data = [...clients];
this.applyClientFilters();
}
});
});
}
applyClientFilters() {
const status = this.statusFilter;
const legal = this.legalFormFilter;
const ckyc = this.ckycFilter;
const filtered = (this.allRows || []).filter((row) => {
const code = (row?.status?.code || '').toLowerCase();
if (status && !code.includes(status)) {
return false;
}
if (legal && String(row?.legalForm?.id ?? '') !== legal) {
return false;
}
if (ckyc === 'done' && !row._ckycDone) {
return false;
}
if (ckyc === 'pending' && row._ckycDone) {
return false;
}
return true;
});
this.dataSource.data = filtered;
}
pageChanged(event: PageEvent) {
this.pageSize = event.pageSize;
this.currentPage = event.pageIndex;