feat: non-individual entity UI improvements — hide individual-only sections, fix legal form display, send extended fields to API
- Hide Family Members tab/section for non-individual entities in client view, create flow, and preview - Hide Financial & Classification section for non-individual entities in personal data and preview - Fix legal form column in clients list — fetch legalForm from client API for correct display - Add person/business icon before client name in list rows - Remove unsupportedNpd filter — send authorizedSignatory, additionalInfo, dateOfRegistration to API - Add registration number format hint (mat-hint) based on constitution type - Add spacing between verification row and constitution type dropdowns - Reduce table cell padding and prevent action buttons from being clipped - Add missing MPL-2.0 license headers Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
ab01111424
commit
b890d24bb7
@@ -23,6 +23,12 @@
|
||||
</div>
|
||||
}
|
||||
@if (isPerson()) {
|
||||
@if (clientViewData.salutation) {
|
||||
<div class="pd-field">
|
||||
<div class="pd-field__label">Salutation</div>
|
||||
<div class="pd-field__value">{{ clientViewData.salutation.name }}</div>
|
||||
</div>
|
||||
}
|
||||
@if (clientViewData.firstname) {
|
||||
<div class="pd-field">
|
||||
<div class="pd-field__label">{{ 'labels.inputs.First Name' | translate }}</div>
|
||||
@@ -44,7 +50,13 @@
|
||||
@if (clientViewData.dateOfBirth) {
|
||||
<div class="pd-field">
|
||||
<div class="pd-field__label">{{ 'labels.inputs.Date of Birth' | translate }}</div>
|
||||
<div class="pd-field__value">{{ clientViewData.dateOfBirth | dateFormat }}</div>
|
||||
<div class="pd-field__value">{{ clientViewData.dateOfBirth | dateFormat:'DD-MMMM-YYYY' }}</div>
|
||||
</div>
|
||||
}
|
||||
@if (clientViewData.ageYears != null) {
|
||||
<div class="pd-field">
|
||||
<div class="pd-field__label">Age</div>
|
||||
<div class="pd-field__value">{{ clientViewData.ageYears }}y {{ clientViewData.ageMonths || 0 }}m {{ clientViewData.ageDays || 0 }}d</div>
|
||||
</div>
|
||||
}
|
||||
@if (clientViewData.gender) {
|
||||
@@ -53,11 +65,29 @@
|
||||
<div class="pd-field__value">{{ clientViewData.gender.name }}</div>
|
||||
</div>
|
||||
}
|
||||
@if (clientViewData.maritalStatus) {
|
||||
<div class="pd-field">
|
||||
<div class="pd-field__label">Marital Status</div>
|
||||
<div class="pd-field__value">{{ clientViewData.maritalStatus.name }}</div>
|
||||
</div>
|
||||
}
|
||||
@if (clientViewData.isMinor != null) {
|
||||
<div class="pd-field">
|
||||
<div class="pd-field__label">Minor</div>
|
||||
<div class="pd-field__value">
|
||||
<span class="pd-verify-badge" [class.pd-verify-badge--verified]="!clientViewData.isMinor" [class.pd-verify-badge--pending]="clientViewData.isMinor">
|
||||
{{ clientViewData.isMinor ? 'Yes (Age < 10)' : 'No' }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
<div class="pd-field">
|
||||
<div class="pd-field__label">{{ 'labels.inputs.Is staff' | translate }}</div>
|
||||
<div class="pd-field__value">{{
|
||||
clientViewData.isStaff ? ('labels.commons.Yes' | translate) : ('labels.commons.No' | translate)
|
||||
}}</div>
|
||||
<div class="pd-field__value">
|
||||
<span class="pd-verify-badge" [class.pd-verify-badge--verified]="clientViewData.isStaff" [class.pd-verify-badge--pending]="!clientViewData.isStaff">
|
||||
{{ clientViewData.isStaff ? 'Yes' : 'No' }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
@if (isLegalEntity()) {
|
||||
@@ -70,16 +100,20 @@
|
||||
@if (clientViewData.dateOfBirth) {
|
||||
<div class="pd-field">
|
||||
<div class="pd-field__label">{{ 'labels.inputs.Incorporation Date' | translate }}</div>
|
||||
<div class="pd-field__value">{{ clientViewData.dateOfBirth | dateFormat }}</div>
|
||||
<div class="pd-field__value">{{ clientViewData.dateOfBirth | dateFormat:'DD-MM-YYYY' }}</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
@if (clientViewData.legalForm) {
|
||||
<div class="pd-field">
|
||||
<div class="pd-field__label">{{ 'labels.inputs.Legal Form' | translate }}</div>
|
||||
<div class="pd-field__value">{{ clientViewData.legalForm.value }}</div>
|
||||
<div class="pd-field__value">{{ clientViewData.legalForm.id === 1 ? 'Individual' : 'Non-Individual' }}</div>
|
||||
</div>
|
||||
}
|
||||
<div class="pd-field">
|
||||
<div class="pd-field__label">Nationality</div>
|
||||
<div class="pd-field__value">{{ clientViewData.nationalityId || clientViewData.nationality || 'Indian' }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -100,10 +134,6 @@
|
||||
<div class="pd-field__label">{{ 'labels.inputs.CIF Number' | translate }}</div>
|
||||
<div class="pd-field__value monospace">{{ clientViewData.cifNumber || '-' }}</div>
|
||||
</div>
|
||||
<div class="pd-field">
|
||||
<div class="pd-field__label">{{ 'labels.inputs.External Id' | translate }}</div>
|
||||
<div class="pd-field__value monospace">{{ clientViewData.externalId || '-' }}</div>
|
||||
</div>
|
||||
<div class="pd-field">
|
||||
<div class="pd-field__label">{{ 'labels.inputs.Office' | translate }}</div>
|
||||
<div class="pd-field__value">{{ clientViewData.officeName || '-' }}</div>
|
||||
@@ -112,10 +142,10 @@
|
||||
<div class="pd-field__label">{{ 'labels.inputs.Staff' | translate }}</div>
|
||||
<div class="pd-field__value">{{ clientViewData.staffName || ('labels.inputs.Unassigned' | translate) }}</div>
|
||||
</div>
|
||||
@if (clientViewData.savingsAccountId) {
|
||||
@if (clientViewData.savingsAccountNo) {
|
||||
<div class="pd-field">
|
||||
<div class="pd-field__label">{{ 'labels.inputs.Default Savings Account' | translate }}</div>
|
||||
<div class="pd-field__value monospace">{{ clientViewData.savingsAccountId }}</div>
|
||||
<div class="pd-field__value monospace">{{ clientViewData.savingsAccountNo }}</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
@@ -146,7 +176,7 @@
|
||||
@if (clientViewData.clientNonPersonDetails.incorpValidityTillDate) {
|
||||
<div class="pd-field">
|
||||
<div class="pd-field__label">{{ 'labels.inputs.Incorporation Validity Till Date' | translate }}</div>
|
||||
<div class="pd-field__value">{{ clientViewData.clientNonPersonDetails.incorpValidityTillDate | dateFormat }}</div>
|
||||
<div class="pd-field__value">{{ clientViewData.clientNonPersonDetails.incorpValidityTillDate | dateFormat:'DD-MM-YYYY' }}</div>
|
||||
</div>
|
||||
}
|
||||
@if (clientViewData.clientNonPersonDetails.incorpNumber) {
|
||||
@@ -166,11 +196,11 @@
|
||||
</div>
|
||||
}
|
||||
|
||||
<!-- Contact Information -->
|
||||
<!-- Contact Details -->
|
||||
<div class="pd-section">
|
||||
<div class="pd-section__header">
|
||||
<i class="fa fa-phone"></i>
|
||||
<h3>{{ 'labels.heading.Contact Information' | translate }}</h3>
|
||||
<h3>Contact Details</h3>
|
||||
</div>
|
||||
<div class="pd-section__body">
|
||||
<div class="pd-grid">
|
||||
@@ -180,6 +210,14 @@
|
||||
<span class="pd-contact-icon"><i class="fa fa-mobile"></i> {{ clientViewData.mobileNo || '-' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
@if (clientViewData.alternateMobileNo) {
|
||||
<div class="pd-field">
|
||||
<div class="pd-field__label">Alternate Mobile No</div>
|
||||
<div class="pd-field__value">
|
||||
<span class="pd-contact-icon"><i class="fa fa-mobile"></i> {{ clientViewData.alternateMobileNo }}</span>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
<div class="pd-field">
|
||||
<div class="pd-field__label">{{ 'labels.inputs.Email' | translate }}</div>
|
||||
<div class="pd-field__value">
|
||||
@@ -190,14 +228,125 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Classification -->
|
||||
<!-- DIP & Sanctions Verification -->
|
||||
<div class="pd-section">
|
||||
<div class="pd-section__header">
|
||||
<i class="fa fa-tag"></i>
|
||||
<h3>{{ 'labels.heading.Classification' | translate }}</h3>
|
||||
<i class="fa fa-shield"></i>
|
||||
<h3>DIP & Sanctions Verification</h3>
|
||||
</div>
|
||||
<div class="pd-section__body">
|
||||
<div class="pd-grid">
|
||||
<!-- Primary Mobile DIP -->
|
||||
<div class="pd-field">
|
||||
<div class="pd-field__label">Mobile DIP Status</div>
|
||||
<div class="pd-field__value">
|
||||
@if (clientViewData.mobileVerified === true || clientViewData.mobileVerified === 'true' || clientViewData.mobileVerified === 1
|
||||
|| clientViewData.dipVerified === true || clientViewData.dipVerified === 'true' || clientViewData.dipVerified === 1) {
|
||||
<span class="pd-verify-badge pd-verify-badge--verified">
|
||||
<i class="fa fa-check-circle"></i> Verified
|
||||
</span>
|
||||
} @else {
|
||||
<span class="pd-verify-badge pd-verify-badge--pending">
|
||||
<i class="fa fa-clock-o"></i> Pending
|
||||
</span>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
@if (clientViewData.dipTimestamp) {
|
||||
<div class="pd-field">
|
||||
<div class="pd-field__label">DIP Verified On</div>
|
||||
<div class="pd-field__value monospace">{{ formatDateTime(clientViewData.dipTimestamp) }}</div>
|
||||
</div>
|
||||
}
|
||||
@if (clientViewData.dipLookupLogId) {
|
||||
<div class="pd-field">
|
||||
<div class="pd-field__label">DIP Lookup Log ID</div>
|
||||
<div class="pd-field__value monospace">{{ clientViewData.dipLookupLogId }}</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<!-- Alternate Mobile DIP -->
|
||||
@if (clientViewData.alternateMobileNo) {
|
||||
<div class="pd-field">
|
||||
<div class="pd-field__label">Alternate Mobile DIP Status</div>
|
||||
<div class="pd-field__value">
|
||||
@if (clientViewData.alternateDipVerified === true || clientViewData.alternateDipVerified === 'true' || clientViewData.alternateDipVerified === 1) {
|
||||
<span class="pd-verify-badge pd-verify-badge--verified">
|
||||
<i class="fa fa-check-circle"></i> Verified
|
||||
</span>
|
||||
} @else {
|
||||
<span class="pd-verify-badge pd-verify-badge--pending">
|
||||
<i class="fa fa-clock-o"></i> Pending
|
||||
</span>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
@if (clientViewData.alternateDipTimestamp) {
|
||||
<div class="pd-field">
|
||||
<div class="pd-field__label">Alternate DIP Verified On</div>
|
||||
<div class="pd-field__value monospace">{{ formatDateTime(clientViewData.alternateDipTimestamp) }}</div>
|
||||
</div>
|
||||
}
|
||||
@if (clientViewData.alternateDipLookupLogId) {
|
||||
<div class="pd-field">
|
||||
<div class="pd-field__label">Alternate DIP Log ID</div>
|
||||
<div class="pd-field__value monospace">{{ clientViewData.alternateDipLookupLogId }}</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
<!-- Sanctions / Name Screening -->
|
||||
<div class="pd-field">
|
||||
<div class="pd-field__label">Name Screening (Sanctions)</div>
|
||||
<div class="pd-field__value">
|
||||
@if (clientViewData.nameVerified === true || clientViewData.nameVerified === 'true' || clientViewData.nameVerified === 1) {
|
||||
<span class="pd-verify-badge pd-verify-badge--verified"><i class="fa fa-check-circle"></i> Clear</span>
|
||||
} @else if (clientViewData.nameVerified === false || clientViewData.nameVerified === 'false' || clientViewData.nameVerified === 0) {
|
||||
<span class="pd-verify-badge pd-verify-badge--danger"><i class="fa fa-exclamation-triangle"></i> Match Found</span>
|
||||
} @else {
|
||||
<span class="pd-verify-badge pd-verify-badge--pending"><i class="fa fa-clock-o"></i> Pending</span>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
@if (clientViewData.screeningLogId) {
|
||||
<div class="pd-field">
|
||||
<div class="pd-field__label">Screening Log ID</div>
|
||||
<div class="pd-field__value monospace">{{ clientViewData.screeningLogId }}</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Financial & Classification (Individual only) -->
|
||||
@if (clientViewData?.legalForm?.id !== 2) {
|
||||
<div class="pd-section">
|
||||
<div class="pd-section__header">
|
||||
<i class="fa fa-chart-line"></i>
|
||||
<h3>Financial & Classification</h3>
|
||||
</div>
|
||||
<div class="pd-section__body">
|
||||
<div class="pd-grid">
|
||||
<div class="pd-field">
|
||||
<div class="pd-field__label">Monthly Income</div>
|
||||
<div class="pd-field__value">
|
||||
@if (clientViewData.monthlyIncome != null && clientViewData.monthlyIncome !== '') {
|
||||
<span class="monospace">₹ {{ clientViewData.monthlyIncome | number }}</span>
|
||||
} @else {
|
||||
-
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class="pd-field">
|
||||
<div class="pd-field__label">Annual Turnover (Last FY)</div>
|
||||
<div class="pd-field__value">
|
||||
@if (clientViewData.annualTurnover != null && clientViewData.annualTurnover !== '') {
|
||||
<span class="monospace">₹ {{ clientViewData.annualTurnover | number }}</span>
|
||||
} @else {
|
||||
-
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
@if (clientViewData.clientType) {
|
||||
<div class="pd-field">
|
||||
<div class="pd-field__label">{{ 'labels.inputs.Client Type' | translate }}</div>
|
||||
@@ -222,14 +371,39 @@
|
||||
<div class="pd-field__value">{{ clientViewData.occupation.name }}</div>
|
||||
</div>
|
||||
}
|
||||
@if (!clientViewData.clientType && !clientViewData.clientClassification) {
|
||||
<div class="pd-field full-width">
|
||||
<div class="pd-field__value no-data">{{ 'labels.commons.No classification data available' | translate }}</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<!-- Guardian Details (Minor) -->
|
||||
@if (clientViewData.isMinor && clientViewData.guardianClientId) {
|
||||
<div class="pd-section">
|
||||
<div class="pd-section__header">
|
||||
<i class="fa fa-user-shield"></i>
|
||||
<h3>Guardian Details</h3>
|
||||
<span class="pd-section__badge pd-section__badge--minor">Minor</span>
|
||||
</div>
|
||||
<div class="pd-section__body">
|
||||
<div class="pd-grid">
|
||||
<div class="pd-field">
|
||||
<div class="pd-field__label">Guardian Name</div>
|
||||
<div class="pd-field__value">{{ clientViewData.guardianClientDisplayName || '-' }}</div>
|
||||
</div>
|
||||
<div class="pd-field">
|
||||
<div class="pd-field__label">Guardian Client ID</div>
|
||||
<div class="pd-field__value monospace">{{ clientViewData.guardianClientId }}</div>
|
||||
</div>
|
||||
@if (clientViewData.guardianRelation) {
|
||||
<div class="pd-field">
|
||||
<div class="pd-field__label">Relationship</div>
|
||||
<div class="pd-field__value">{{ clientViewData.guardianRelation }}</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<!-- Group Membership -->
|
||||
@if (clientViewData.groups && clientViewData.groups.length > 0) {
|
||||
@@ -262,19 +436,19 @@
|
||||
@if (clientViewData.timeline?.submittedOnDate) {
|
||||
<div class="pd-field">
|
||||
<div class="pd-field__label">{{ 'labels.inputs.Submitted On' | translate }}</div>
|
||||
<div class="pd-field__value">{{ clientViewData.timeline.submittedOnDate | dateFormat }}</div>
|
||||
<div class="pd-field__value">{{ clientViewData.timeline.submittedOnDate | dateFormat:'DD-MM-YYYY' }}</div>
|
||||
</div>
|
||||
}
|
||||
@if (clientViewData.activationDate) {
|
||||
<div class="pd-field">
|
||||
<div class="pd-field__label">{{ 'labels.inputs.Activation Date' | translate }}</div>
|
||||
<div class="pd-field__value">{{ clientViewData.activationDate | dateFormat }}</div>
|
||||
<div class="pd-field__value">{{ clientViewData.activationDate | dateFormat:'DD-MM-YYYY' }}</div>
|
||||
</div>
|
||||
}
|
||||
@if (clientViewData.timeline?.closedOnDate) {
|
||||
<div class="pd-field">
|
||||
<div class="pd-field__label">{{ 'labels.inputs.Closed Date' | translate }}</div>
|
||||
<div class="pd-field__value">{{ clientViewData.timeline.closedOnDate | dateFormat }}</div>
|
||||
<div class="pd-field__value">{{ clientViewData.timeline.closedOnDate | dateFormat:'DD-MM-YYYY' }}</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -59,6 +59,20 @@ $teal: #00897b;
|
||||
}
|
||||
}
|
||||
|
||||
.pd-section__badge {
|
||||
font-size: 10px;
|
||||
font-weight: 700;
|
||||
padding: 2px 10px;
|
||||
border-radius: 10px;
|
||||
margin-left: auto;
|
||||
letter-spacing: 0.3px;
|
||||
|
||||
&--minor {
|
||||
background: #fef2f2;
|
||||
color: #dc2626;
|
||||
}
|
||||
}
|
||||
|
||||
.pd-section__body {
|
||||
padding: 16px 20px;
|
||||
}
|
||||
@@ -205,3 +219,34 @@ $teal: #00897b;
|
||||
color: $gray-500;
|
||||
}
|
||||
}
|
||||
|
||||
// DIP Verification badges
|
||||
.pd-verify-badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
padding: 3px 12px;
|
||||
border-radius: 12px;
|
||||
|
||||
i { font-size: 12px; }
|
||||
|
||||
&--verified {
|
||||
background: #ecfdf5;
|
||||
color: #059669;
|
||||
border: 1px solid #a7f3d0;
|
||||
}
|
||||
|
||||
&--pending {
|
||||
background: #fffbeb;
|
||||
color: #d97706;
|
||||
border: 1px solid #fde68a;
|
||||
}
|
||||
|
||||
&--danger {
|
||||
background: #fef2f2;
|
||||
color: #dc2626;
|
||||
border: 1px solid #fecaca;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
/** Custom Imports */
|
||||
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
|
||||
import { DateFormatPipe } from '../../../pipes/date-format.pipe';
|
||||
import { DecimalPipe } from '@angular/common';
|
||||
import { LegalFormId } from 'app/clients/models/legal-form.enum';
|
||||
|
||||
/** Interfaces */
|
||||
@@ -56,7 +57,8 @@ interface ClientViewData {
|
||||
standalone: true,
|
||||
imports: [
|
||||
...STANDALONE_SHARED_IMPORTS,
|
||||
DateFormatPipe
|
||||
DateFormatPipe,
|
||||
DecimalPipe
|
||||
]
|
||||
})
|
||||
export class PersonalDataTabComponent {
|
||||
@@ -84,4 +86,24 @@ export class PersonalDataTabComponent {
|
||||
isLegalEntity(): boolean {
|
||||
return this.clientViewData?.legalForm?.id === LegalFormId.ENTITY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format ISO timestamp to DD-MM-YYYY HH:MM:SS
|
||||
*/
|
||||
formatDateTime(value: string): string {
|
||||
if (!value) return '-';
|
||||
try {
|
||||
const d = new Date(value);
|
||||
if (isNaN(d.getTime())) return value;
|
||||
const dd = String(d.getDate()).padStart(2, '0');
|
||||
const mm = String(d.getMonth() + 1).padStart(2, '0');
|
||||
const yyyy = d.getFullYear();
|
||||
const hh = String(d.getHours()).padStart(2, '0');
|
||||
const min = String(d.getMinutes()).padStart(2, '0');
|
||||
const ss = String(d.getSeconds()).padStart(2, '0');
|
||||
return `${dd}-${mm}-${yyyy} ${hh}:${min}:${ss}`;
|
||||
} catch {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user