WEB-602 Use the env var for hidding client data information MIFOS_COMPLIANCE_HIDE_CLIENT_DATA and it is enabled to true the display name must be hidden using * characters for replacing the letters. (#3017)
This commit is contained in:
@@ -58,8 +58,14 @@
|
|||||||
[ngClass]="clientViewData.status.code | statusLookup"
|
[ngClass]="clientViewData.status.code | statusLookup"
|
||||||
matTooltip="{{ 'labels.status.' + clientViewData.status.value | translate }}"
|
matTooltip="{{ 'labels.status.' + clientViewData.status.value | translate }}"
|
||||||
></i>
|
></i>
|
||||||
<b>{{ 'labels.inputs.Client Name' | translate }} :</b
|
<b>{{ 'labels.inputs.Client Name' | translate }} :</b>
|
||||||
><mifosx-entity-name entityName="{{ clientViewData.displayName }}"></mifosx-entity-name>
|
<mifosx-entity-name
|
||||||
|
[entityName]="
|
||||||
|
complianceHideClientData ? maskName(clientViewData.displayName) : clientViewData.displayName
|
||||||
|
"
|
||||||
|
[display]="'right'"
|
||||||
|
[hideCopy]="complianceHideClientData"
|
||||||
|
></mifosx-entity-name>
|
||||||
</h3>
|
</h3>
|
||||||
<div class="flex-5 align-end-center">
|
<div class="flex-5 align-end-center">
|
||||||
<button mat-icon-button [matMenuTriggerFor]="clientMenu" aria-label="Client actions" yPosition="below">
|
<button mat-icon-button [matMenuTriggerFor]="clientMenu" aria-label="Client actions" yPosition="below">
|
||||||
@@ -79,7 +85,7 @@
|
|||||||
<td>
|
<td>
|
||||||
<b>{{ 'labels.inputs.Office' | translate }}</b>
|
<b>{{ 'labels.inputs.Office' | translate }}</b>
|
||||||
</td>
|
</td>
|
||||||
<td><mifosx-entity-name entityName="{{ clientViewData.officeName }}"></mifosx-entity-name></td>
|
<td><mifosx-entity-name [entityName]="clientViewData.officeName"></mifosx-entity-name></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
@@ -93,8 +99,11 @@
|
|||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<mifosx-external-identifier
|
<mifosx-external-identifier
|
||||||
externalId="{{ clientViewData.externalId }}"
|
[externalId]="
|
||||||
completed="true"
|
complianceHideClientData ? maskValue(clientViewData.externalId) : clientViewData.externalId
|
||||||
|
"
|
||||||
|
[completed]="true"
|
||||||
|
[hideCopy]="complianceHideClientData"
|
||||||
></mifosx-external-identifier>
|
></mifosx-external-identifier>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -151,8 +160,11 @@
|
|||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<mifosx-external-identifier
|
<mifosx-external-identifier
|
||||||
externalId="{{ clientViewData.mobileNo }}"
|
[externalId]="
|
||||||
completed="true"
|
complianceHideClientData ? maskValue(clientViewData.mobileNo) : clientViewData.mobileNo
|
||||||
|
"
|
||||||
|
[completed]="true"
|
||||||
|
[hideCopy]="complianceHideClientData"
|
||||||
></mifosx-external-identifier>
|
></mifosx-external-identifier>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -162,8 +174,13 @@
|
|||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<mifosx-external-identifier
|
<mifosx-external-identifier
|
||||||
externalId="{{ clientViewData.emailAddress }}"
|
[externalId]="
|
||||||
completed="true"
|
complianceHideClientData
|
||||||
|
? maskEmail(clientViewData.emailAddress)
|
||||||
|
: clientViewData.emailAddress
|
||||||
|
"
|
||||||
|
[completed]="true"
|
||||||
|
[hideCopy]="complianceHideClientData"
|
||||||
></mifosx-external-identifier>
|
></mifosx-external-identifier>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
/** Angular Imports */
|
/** Angular Imports */
|
||||||
import { Component, OnInit, inject } from '@angular/core';
|
import { Component, OnInit, inject } from '@angular/core';
|
||||||
|
import { environment } from 'src/environments/environment';
|
||||||
import { ActivatedRoute, Router, RouterLink, RouterLinkActive, RouterOutlet } from '@angular/router';
|
import { ActivatedRoute, Router, RouterLink, RouterLinkActive, RouterOutlet } from '@angular/router';
|
||||||
import { DomSanitizer } from '@angular/platform-browser';
|
import { DomSanitizer } from '@angular/platform-browser';
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
@@ -79,6 +80,53 @@ import { formatTabLabel } from 'app/shared/utils/format-tab-label.util';
|
|||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class ClientsViewComponent implements OnInit {
|
export class ClientsViewComponent implements OnInit {
|
||||||
|
complianceHideClientData = environment.complianceHideClientData;
|
||||||
|
/**
|
||||||
|
* Mask a string, keeping first and last letter, masking the rest with *
|
||||||
|
*/
|
||||||
|
maskName(name: string): string {
|
||||||
|
if (!name) return '';
|
||||||
|
return name
|
||||||
|
.trim()
|
||||||
|
.split(/(\s+)/)
|
||||||
|
.map((word) => {
|
||||||
|
if (!word.trim()) return word;
|
||||||
|
if (word.length <= 2) return word[0] + '*';
|
||||||
|
return word[0] + '*'.repeat(word.length - 2) + word[word.length - 1];
|
||||||
|
})
|
||||||
|
.join('');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mask external id, mobile, etc (show only first char, rest as *)
|
||||||
|
*/
|
||||||
|
maskValue(val: string): string {
|
||||||
|
if (!val) return '';
|
||||||
|
if (val.length <= 2) return val[0] + '*';
|
||||||
|
return val[0] + '*'.repeat(val.length - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mask email: v********@f*******
|
||||||
|
*/
|
||||||
|
maskEmail(email: string): string {
|
||||||
|
if (!email) return '';
|
||||||
|
const [
|
||||||
|
user,
|
||||||
|
domain
|
||||||
|
] = email.split('@');
|
||||||
|
if (!user || !domain || user.length < 1) return this.maskValue(email);
|
||||||
|
let maskedUser = user.length > 1 ? user[0] + '*'.repeat(user.length - 1) : user[0] + '*';
|
||||||
|
const domainLabel = domain.split('.')[0] || '';
|
||||||
|
const domainMaskLen = Math.max(0, domainLabel.length - 1);
|
||||||
|
let maskedDomain = domainLabel.length > 0 ? domainLabel[0] + '*'.repeat(domainMaskLen) : '';
|
||||||
|
let domainRest = '';
|
||||||
|
if (domain.length > domainLabel.length) {
|
||||||
|
domainRest = domain.substring(domainLabel.length);
|
||||||
|
}
|
||||||
|
if (!maskedDomain) return this.maskValue(email);
|
||||||
|
return maskedUser + '@' + maskedDomain + domainRest;
|
||||||
|
}
|
||||||
formatTabLabel(label: string): string {
|
formatTabLabel(label: string): string {
|
||||||
return formatTabLabel(label);
|
return formatTabLabel(label);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<span (mouseenter)="mouseEnter()" (mouseleave)="mouseLeave()">
|
<span (mouseenter)="mouseEnter()" (mouseleave)="mouseLeave()">
|
||||||
@if (displayL && iconVisible) {
|
@if (displayL && iconVisible && !hideCopy) {
|
||||||
<span class="m-l-5" (click)="copyValue()"
|
<span class="m-l-5" (click)="copyValue()"
|
||||||
><b><fa-icon icon="copy" size="sm" title="{{ 'labels.text.Copy Account Number' | translate }}"></fa-icon></b
|
><b><fa-icon icon="copy" size="sm" title="{{ 'labels.text.Copy Account Number' | translate }}"></fa-icon></b
|
||||||
></span>
|
></span>
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
<span class="m-l-5"
|
<span class="m-l-5"
|
||||||
><b>{{ entityName }}</b></span
|
><b>{{ entityName }}</b></span
|
||||||
>
|
>
|
||||||
@if (displayR && iconVisible) {
|
@if (displayR && iconVisible && !hideCopy) {
|
||||||
<span class="m-l-3" (click)="copyValue()"
|
<span class="m-l-3" (click)="copyValue()"
|
||||||
><b><fa-icon icon="copy" size="sm" title="{{ 'labels.text.Copy Account Number' | translate }}"></fa-icon></b
|
><b><fa-icon icon="copy" size="sm" title="{{ 'labels.text.Copy Account Number' | translate }}"></fa-icon></b
|
||||||
></span>
|
></span>
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ export class EntityNameComponent implements OnInit {
|
|||||||
|
|
||||||
@Input() entityName: string;
|
@Input() entityName: string;
|
||||||
@Input() display = 'right';
|
@Input() display = 'right';
|
||||||
|
@Input() hideCopy = false;
|
||||||
|
|
||||||
iconVisible = false;
|
iconVisible = false;
|
||||||
displayL = false;
|
displayL = false;
|
||||||
@@ -36,7 +37,9 @@ export class EntityNameComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
copyValue(): void {
|
copyValue(): void {
|
||||||
this.clipboard.copy(this.entityName);
|
if (!this.hideCopy) {
|
||||||
|
this.clipboard.copy(this.entityName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mouseEnter() {
|
mouseEnter() {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
@if (!emptyValue) {
|
@if (!emptyValue) {
|
||||||
<span (mouseenter)="mouseEnter()" (mouseleave)="mouseLeave()">
|
<span (mouseenter)="mouseEnter()" (mouseleave)="mouseLeave()">
|
||||||
@if (displayL && iconVisible) {
|
@if (displayL && iconVisible && !hideCopy) {
|
||||||
<span (click)="copyValue()"><fa-icon icon="copy" size="sm" title="Copy External Id"></fa-icon></span>
|
<span (click)="copyValue()"><fa-icon icon="copy" size="sm" title="Copy External Id"></fa-icon></span>
|
||||||
}
|
}
|
||||||
@if (displayL && !completed && iconVisible && isLongValue()) {
|
@if (displayL && !completed && iconVisible && isLongValue()) {
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
@if (displayR && !completed && iconVisible && isLongValue()) {
|
@if (displayR && !completed && iconVisible && isLongValue()) {
|
||||||
<span class="m-l-5" (click)="showValue()"><fa-icon icon="eye" size="sm" [title]="externalId"></fa-icon></span>
|
<span class="m-l-5" (click)="showValue()"><fa-icon icon="eye" size="sm" [title]="externalId"></fa-icon></span>
|
||||||
}
|
}
|
||||||
@if (displayR && iconVisible) {
|
@if (displayR && iconVisible && !hideCopy) {
|
||||||
<span class="m-l-3" (click)="copyValue()"
|
<span class="m-l-3" (click)="copyValue()"
|
||||||
><fa-icon icon="copy" size="sm" title="Copy External Id"></fa-icon
|
><fa-icon icon="copy" size="sm" title="Copy External Id"></fa-icon
|
||||||
></span>
|
></span>
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ export class ExternalIdentifierComponent implements OnInit {
|
|||||||
@Input() externalId: string;
|
@Input() externalId: string;
|
||||||
@Input() completed = false;
|
@Input() completed = false;
|
||||||
@Input() display = 'right';
|
@Input() display = 'right';
|
||||||
|
@Input() hideCopy = false;
|
||||||
|
|
||||||
iconVisible = false;
|
iconVisible = false;
|
||||||
displayL = false;
|
displayL = false;
|
||||||
@@ -54,8 +55,10 @@ export class ExternalIdentifierComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
copyValue(): void {
|
copyValue(): void {
|
||||||
this.clipboard.copy(this.externalId);
|
if (!this.hideCopy) {
|
||||||
this.alertService.alert({ type: 'Clipboard', message: 'Copied: ' + this.externalId });
|
this.clipboard.copy(this.externalId);
|
||||||
|
this.alertService.alert({ type: 'Clipboard', message: 'Copied: ' + this.externalId });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mouseEnter() {
|
mouseEnter() {
|
||||||
|
|||||||
Reference in New Issue
Block a user