Merge branch 'dev' into feature/bugfix
Conflicts resolved in: - src/app/clients/clients-view/ckyc-tab/ckyc-tab.component.html - src/app/clients/clients-view/ckyc-tab/ckyc-tab.component.ts Kept dev's CKYC architecture (upload dialog, real per-artefact endpoints) and layered feature/bugfix's fixes on top: upload file validation, missing-file badge, silent preview download, and image/PDF view button. Also includes the CKYC "Image of Client" upload-state fix and the client-change state-leak fix in the same component. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -82,12 +82,13 @@
|
||||
<strong class="kyc-doc-alert__title">{{ kycDocumentAlertTitle }}</strong>
|
||||
<p class="kyc-doc-alert__text">{{ kycDocumentAlertMessage }}</p>
|
||||
</div>
|
||||
<!-- Same dialog as the document's own row: the banner is asking for exactly that. -->
|
||||
<button
|
||||
mat-flat-button
|
||||
color="primary"
|
||||
type="button"
|
||||
class="kyc-doc-alert__action"
|
||||
(click)="toggleEditMode()"
|
||||
(click)="updateKycDocument()"
|
||||
>
|
||||
Update Document
|
||||
</button>
|
||||
@@ -470,7 +471,11 @@
|
||||
}
|
||||
</span>
|
||||
<span class="kv-table__col kv-table__col--action">
|
||||
<button mat-stroked-button class="kv-action-btn" type="button" (click)="toggleEditMode()">Update</button>
|
||||
<!-- The document is re-collected in its own dialog, the way PAN and Aadhaar are dealt
|
||||
with on their rows, rather than by opening the whole KYC form for editing. -->
|
||||
<button mat-stroked-button class="kv-action-btn" type="button" (click)="updateKycDocument()">
|
||||
Update
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
}
|
||||
@@ -1188,15 +1193,81 @@
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<!-- The scans live with the document itself, on the identifier the customer's
|
||||
original was attached to. Re-scanning is done there rather than duplicated
|
||||
here, so both sides, the cropper and the replace-in-place all behave the
|
||||
same way they did when the document was first collected. -->
|
||||
<a class="kyc-doc-scans-link" [routerLink]="['/clients', clientId, 'edit']">
|
||||
<mat-icon>photo_library</mat-icon>
|
||||
<span>Replace the scanned front / back of this document</span>
|
||||
<mat-icon class="kyc-doc-scans-link__go">chevron_right</mat-icon>
|
||||
</a>
|
||||
<!-- The scan, where the document it belongs to is. Re-collecting an expiring
|
||||
document is what this panel is for, so sending the officer to the client
|
||||
edit screen to change the image made them leave the record they were
|
||||
working on and find the same document again. -->
|
||||
<div class="kyc-doc-scans">
|
||||
<div class="kyc-doc-scans__head">
|
||||
<mat-icon>photo_library</mat-icon>
|
||||
<span>Scanned document</span>
|
||||
@if (docScansLoading) {
|
||||
<mat-progress-spinner diameter="16" mode="indeterminate"></mat-progress-spinner>
|
||||
}
|
||||
</div>
|
||||
|
||||
@if (!docScansLoading && !docScans.front && !docScans.back) {
|
||||
<div class="kyc-doc-scans__empty">No scan is on file for this document. Upload one below.</div>
|
||||
}
|
||||
|
||||
<div class="kyc-doc-scans__sides">
|
||||
@for (slot of docScanSlots; track slot) {
|
||||
<div class="kyc-doc-side">
|
||||
<div class="kyc-doc-side__label">{{ slot === 'front' ? 'Front' : 'Back' }}</div>
|
||||
|
||||
<div class="kyc-doc-side__frame">
|
||||
@if (docScanOf(slot)?.previewUrl) {
|
||||
<img
|
||||
[src]="docScanOf(slot)!.previewUrl"
|
||||
[alt]="slot === 'front' ? 'Front of document' : 'Back of document'"
|
||||
/>
|
||||
} @else if (docScanOf(slot)) {
|
||||
<!-- On file but not an image (a PDF, say) — named rather than shown. -->
|
||||
<div class="kyc-doc-side__file">
|
||||
<mat-icon>description</mat-icon>
|
||||
<span>{{ docScanOf(slot)!.fileName }}</span>
|
||||
</div>
|
||||
} @else {
|
||||
<div class="kyc-doc-side__none">Not on file</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
mat-stroked-button
|
||||
class="kyc-doc-side__btn"
|
||||
[disabled]="!!docScanUploading || docScansLoading"
|
||||
(click)="scanInput.click()"
|
||||
>
|
||||
@if (docScanUploading === slot) {
|
||||
<mat-progress-spinner diameter="16" mode="indeterminate"></mat-progress-spinner>
|
||||
Uploading…
|
||||
} @else {
|
||||
{{ docScanOf(slot) ? 'Replace' : 'Upload' }}
|
||||
}
|
||||
</button>
|
||||
<input
|
||||
#scanInput
|
||||
type="file"
|
||||
hidden
|
||||
accept="image/*,application/pdf"
|
||||
(change)="onDocScanSelected($event, slot)"
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
@if (docScanError) {
|
||||
<div class="kyc-doc-scans__msg kyc-doc-scans__msg--err">
|
||||
<mat-icon>error_outline</mat-icon><span>{{ docScanError }}</span>
|
||||
</div>
|
||||
}
|
||||
@if (docScanSuccess) {
|
||||
<div class="kyc-doc-scans__msg kyc-doc-scans__msg--ok">
|
||||
<mat-icon>check_circle</mat-icon><span>{{ docScanSuccess }}</span>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user