- Raise isMinor threshold from age <10 to <18 (legal definition), cascading correctly to guardian requirement, KYC document filtering, and Education Level/Degree Qualification visibility (now shown for all ages, not hidden for minors). - Load and display previously-uploaded Senior Citizen proof / PWD certificate documents on edit (view/replace/remove), instead of always showing an empty upload prompt. - Fix seniorPwdDocsComplete to accept an existing certificate, not just a freshly-picked file. - Add DocumentPreviewDialogComponent: a reusable in-app modal (image/PDF/download) used in place of window.open() for saved KYC/address/senior-citizen/PWD documents — avoids popup blockers (fired only after the async download resolved) and Chrome/Edge's failure to paint large base64 data: URLs on first open. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
82 lines
2.5 KiB
TypeScript
82 lines
2.5 KiB
TypeScript
/**
|
|
* Copyright since 2025 Mifos Initiative
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*/
|
|
|
|
/** Angular Imports */
|
|
import { Component, OnDestroy, inject } from '@angular/core';
|
|
import {
|
|
MatDialogRef,
|
|
MAT_DIALOG_DATA,
|
|
MatDialogTitle,
|
|
MatDialogContent,
|
|
MatDialogActions,
|
|
MatDialogClose
|
|
} from '@angular/material/dialog';
|
|
import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';
|
|
import { CdkScrollable } from '@angular/cdk/scrolling';
|
|
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
|
|
|
|
export interface DocumentPreviewDialogData {
|
|
blob: Blob;
|
|
title?: string;
|
|
fileName?: string;
|
|
}
|
|
|
|
/**
|
|
* Generic in-app document preview dialog — shows an image inline or a PDF in an embedded
|
|
* viewer, with a Download fallback for anything else. Used in place of window.open() for
|
|
* saved KYC/address/senior-citizen/PWD documents: opening a new browser tab is subject to
|
|
* popup blockers (fires only after the async download resolves) and, for images, Chrome/Edge
|
|
* frequently fail to paint a huge base64 data: URL until the tab is manually refreshed.
|
|
*/
|
|
@Component({
|
|
selector: 'mifosx-document-preview-dialog',
|
|
templateUrl: './document-preview-dialog.component.html',
|
|
styleUrls: ['./document-preview-dialog.component.scss'],
|
|
imports: [
|
|
...STANDALONE_SHARED_IMPORTS,
|
|
MatDialogTitle,
|
|
CdkScrollable,
|
|
MatDialogContent,
|
|
MatDialogActions,
|
|
MatDialogClose
|
|
]
|
|
})
|
|
export class DocumentPreviewDialogComponent implements OnDestroy {
|
|
dialogRef = inject<MatDialogRef<DocumentPreviewDialogComponent>>(MatDialogRef);
|
|
private sanitizer = inject(DomSanitizer);
|
|
data = inject<DocumentPreviewDialogData>(MAT_DIALOG_DATA);
|
|
|
|
private readonly objectUrl: string;
|
|
readonly safeUrl: SafeResourceUrl;
|
|
readonly isImage: boolean;
|
|
readonly isPdf: boolean;
|
|
|
|
constructor() {
|
|
this.objectUrl = URL.createObjectURL(this.data.blob);
|
|
this.safeUrl = this.sanitizer.bypassSecurityTrustResourceUrl(this.objectUrl);
|
|
const type = this.data.blob.type || '';
|
|
this.isImage = type.startsWith('image/');
|
|
this.isPdf = type === 'application/pdf';
|
|
}
|
|
|
|
ngOnDestroy(): void {
|
|
URL.revokeObjectURL(this.objectUrl);
|
|
}
|
|
|
|
get previewUrl(): string {
|
|
return this.objectUrl;
|
|
}
|
|
|
|
download(): void {
|
|
const a = document.createElement('a');
|
|
a.href = this.objectUrl;
|
|
a.download = this.data.fileName || 'document';
|
|
a.click();
|
|
}
|
|
}
|