WEB-751 feat: add draw signature capability for clients (#3212)

This commit is contained in:
Shubham Kumar
2026-02-22 19:05:22 -06:00
committed by GitHub
parent f0db7491ab
commit 2e0d403a79
20 changed files with 206 additions and 0 deletions
+7
View File
@@ -44,6 +44,7 @@
"moment": "^2.29.4",
"ngx-mat-select-search": "^8.0.2",
"rxjs": "^7.8.2",
"signature_pad": "^5.1.3",
"tinymce": "^8.2.2",
"tslib": "^2.8.1",
"vkbeautify": "^0.99.3",
@@ -21912,6 +21913,12 @@
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/signature_pad": {
"version": "5.1.3",
"resolved": "https://registry.npmjs.org/signature_pad/-/signature_pad-5.1.3.tgz",
"integrity": "sha512-zyxW5vuJVnQdGcU+kAj9FYl7WaAunY3kA5S7mPg0xJiujL9+sPAWfSQHS5tXaJXDUa4FuZeKhfdCDQ6K3wfkpQ==",
"license": "MIT"
},
"node_modules/sigstore": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/sigstore/-/sigstore-4.1.0.tgz",
+1
View File
@@ -71,6 +71,7 @@
"moment": "^2.29.4",
"ngx-mat-select-search": "^8.0.2",
"rxjs": "^7.8.2",
"signature_pad": "^5.1.3",
"tinymce": "^8.2.2",
"tslib": "^2.8.1",
"vkbeautify": "^0.99.3",
@@ -18,6 +18,7 @@ import { UnassignStaffDialogComponent } from './custom-dialogs/unassign-staff-di
import { UploadSignatureDialogComponent } from './custom-dialogs/upload-signature-dialog/upload-signature-dialog.component';
import { ViewSignatureDialogComponent } from './custom-dialogs/view-signature-dialog/view-signature-dialog.component';
import { DeleteSignatureDialogComponent } from './custom-dialogs/delete-signature-dialog/delete-signature-dialog.component';
import { DrawSignatureDialogComponent } from './custom-dialogs/draw-signature-dialog/draw-signature-dialog.component';
import { DeleteDialogComponent } from 'app/shared/delete-dialog/delete-dialog.component';
import { UploadImageDialogComponent } from './custom-dialogs/upload-image-dialog/upload-image-dialog.component';
import { CaptureImageDialogComponent } from './custom-dialogs/capture-image-dialog/capture-image-dialog.component';
@@ -313,6 +314,8 @@ export class ClientsViewComponent implements OnInit {
viewSignatureDialogRef.afterClosed().subscribe((response: any) => {
if (response.upload) {
this.uploadSignature();
} else if (response.draw) {
this.drawSignature();
} else if (response.delete) {
this.deleteSignature();
}
@@ -334,6 +337,20 @@ export class ClientsViewComponent implements OnInit {
});
}
/**
* Opens draw pad for client signature
*/
private drawSignature() {
const drawSignatureDialogRef = this.dialog.open(DrawSignatureDialogComponent);
drawSignatureDialogRef.afterClosed().subscribe((signature: File) => {
if (signature) {
this.clientsService.uploadClientSignatureImage(this.clientViewData.id, signature).subscribe(() => {
this.reload();
});
}
});
}
/**
* Deletes client signature
*/
@@ -0,0 +1,28 @@
<!--
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/.
-->
<div class="layout-column gap-2px">
<h1 mat-dialog-title>{{ 'labels.heading.Draw Client Signature' | translate }}</h1>
<div class="signature-canvas-container">
<canvas #signatureCanvas class="signature-canvas"></canvas>
</div>
<div align="center">
<button mat-stroked-button color="primary" (click)="clear()">
{{ 'labels.buttons.Clear' | translate }}
</button>
</div>
<mat-dialog-actions align="end">
<button mat-raised-button mat-dialog-close>{{ 'labels.buttons.Cancel' | translate }}</button>
<button mat-raised-button color="primary" [disabled]="isEmpty" (click)="confirm()">
{{ 'labels.buttons.Confirm' | translate }}
</button>
</mat-dialog-actions>
</div>
@@ -0,0 +1,21 @@
/**
* 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/.
*/
.signature-canvas-container {
border: 1px solid #ccc;
border-radius: 4px;
margin: 0 auto;
width: 100%;
max-width: 500px;
}
.signature-canvas {
width: 100%;
height: 200px;
display: block;
}
@@ -0,0 +1,90 @@
/**
* 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, ViewChild, ElementRef, AfterViewInit, OnDestroy, inject } from '@angular/core';
import { MatDialogRef, MatDialogTitle, MatDialogActions, MatDialogClose } from '@angular/material/dialog';
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
/** External Imports */
import SignaturePad from 'signature_pad';
/**
* Draw signature dialog component.
*/
@Component({
selector: 'mifosx-draw-signature-dialog',
templateUrl: './draw-signature-dialog.component.html',
styleUrls: ['./draw-signature-dialog.component.scss'],
imports: [
...STANDALONE_SHARED_IMPORTS,
MatDialogTitle,
MatDialogActions,
MatDialogClose
]
})
export class DrawSignatureDialogComponent implements AfterViewInit, OnDestroy {
dialogRef = inject<MatDialogRef<DrawSignatureDialogComponent>>(MatDialogRef);
/** Canvas element reference */
@ViewChild('signatureCanvas', { static: true }) signatureCanvas: ElementRef<HTMLCanvasElement>;
/** Signature pad instance */
private signaturePad: SignaturePad;
/** Whether the pad has content */
isEmpty = true;
ngAfterViewInit() {
const canvas = this.signatureCanvas.nativeElement;
this.signaturePad = new SignaturePad(canvas, {
backgroundColor: 'rgb(255, 255, 255)'
});
this.signaturePad.addEventListener('endStroke', () => {
this.isEmpty = this.signaturePad.isEmpty();
});
this.resizeCanvas();
}
ngOnDestroy() {
if (this.signaturePad) {
this.signaturePad.off();
}
}
/** Resizes canvas to match its display size for crisp rendering */
private resizeCanvas() {
const canvas = this.signatureCanvas.nativeElement;
const ratio = Math.max(window.devicePixelRatio || 1, 1);
canvas.width = canvas.offsetWidth * ratio;
canvas.height = canvas.offsetHeight * ratio;
canvas.getContext('2d').scale(ratio, ratio);
this.signaturePad.clear();
}
/** Clears the signature pad */
clear() {
this.signaturePad.clear();
this.isEmpty = true;
}
/** Converts the drawn signature to a File and closes the dialog */
confirm() {
if (this.signaturePad.isEmpty()) {
return;
}
const canvas = this.signatureCanvas.nativeElement;
canvas.toBlob((blob: Blob) => {
const file = new File([blob], 'clientSignature.png', { type: 'image/png' });
this.dialogRef.close(file);
}, 'image/png');
}
}
@@ -31,5 +31,8 @@
<button mat-raised-button color="primary" [mat-dialog-close]="{ upload: true }">
{{ 'labels.buttons.Upload' | translate }}
</button>
<button mat-raised-button color="primary" [mat-dialog-close]="{ draw: true }">
{{ 'labels.buttons.Draw' | translate }}
</button>
}
</mat-dialog-actions>
+3
View File
@@ -359,6 +359,7 @@
"Change Password": "Změnit heslo",
"Chargeback": "Zpětné zúčtování",
"Charges Overview": "Přehled poplatků",
"Clear": "Vymazat",
"Client Screen Reports": "Zprávy na obrazovce klienta",
"Close": "Zavřít",
"Close Config. Wizard": "Zavřete Config. kouzelník",
@@ -424,6 +425,7 @@
"Dividends": "Dividendy",
"Download": "Stažení",
"Download CSV": "Stáhnout CSV",
"Draw": "Kreslit",
"Edit": "Upravit",
"Edit Code": "Upravit kód",
"Edit Criteria Definition": "Upravit definici kritérií",
@@ -1014,6 +1016,7 @@
"Disable Withhold Tax": "Zakázat zadržení daně",
"Documents": "Dokumenty",
"Down Payment": "Záloha",
"Draw Client Signature": "Nakreslit podpis",
"Due Collections": "Splatné sbírky",
"Due Savings Collections": "Splatné spořící sbírky",
"Edit": "Upravit",
+3
View File
@@ -359,6 +359,7 @@
"Change Password": "Kennwort ändern",
"Chargeback": "Rückbuchung",
"Charges Overview": "Gebührenübersicht",
"Clear": "Löschen",
"Client Screen Reports": "Kundenbildschirmberichte",
"Close": "Schließen",
"Close Config. Wizard": "Konfiguration schließen. Magier",
@@ -424,6 +425,7 @@
"Dividends": "Dividenden",
"Download": "Herunterladen",
"Download CSV": "CSV herunterladen",
"Draw": "Zeichnen",
"Edit": "Bearbeiten",
"Edit Code": "Code bearbeiten",
"Edit Criteria Definition": "Kriteriendefinition bearbeiten",
@@ -1015,6 +1017,7 @@
"Disable Withhold Tax": "Deaktivieren Sie die Quellensteuer",
"Documents": "Unterlagen",
"Down Payment": "Anzahlung",
"Draw Client Signature": "Unterschrift zeichnen",
"Due Collections": "Fällige Sammlungen",
"Due Savings Collections": "Fällige Spareinzüge",
"Edit": "Bearbeiten",
+3
View File
@@ -397,6 +397,7 @@
"Change Password": "Change Password",
"Chargeback": "Chargeback",
"Charges Overview": "Charges Overview",
"Clear": "Clear",
"Client Screen Reports": "Client Screen Reports",
"Close": "Close",
"Close Config. Wizard": "Close Config. Wizard",
@@ -462,6 +463,7 @@
"Dividends": "Dividends",
"Download": "Download",
"Download CSV": "Download CSV",
"Draw": "Draw",
"Edit": "Edit",
"Edit Code": "Edit Code",
"Edit Criteria Definition": "Edit Criteria Definition",
@@ -1055,6 +1057,7 @@
"Disable Withhold Tax": "Disable Withhold Tax",
"Documents": "Documents",
"Down Payment": "Down Payment",
"Draw Client Signature": "Draw Signature",
"Due Collections": "Due Collections",
"Due Savings Collections": "Due Savings Collections",
"Edit": "Edit",
+3
View File
@@ -359,6 +359,7 @@
"Change Password": "Cambiar la contraseña",
"Chargeback": "Contracargo",
"Charges Overview": "Resumen de cargos",
"Clear": "Borrar",
"Client Screen Reports": "Reportes de pantalla del cliente",
"Close": "Cerrar",
"Close Config. Wizard": "Cerrar",
@@ -424,6 +425,7 @@
"Dividends": "Dividendos",
"Download": "Descargar",
"Download CSV": "Descargar CSV",
"Draw": "Dibujar",
"Edit": "Editar",
"Edit Code": "Editar Código",
"Edit Criteria Definition": "Editar Definición de Criterios",
@@ -1014,6 +1016,7 @@
"Disable Withhold Tax": "Desactivar retención de impuestos",
"Documents": "Documentos",
"Down Payment": "Pago Inicial",
"Draw Client Signature": "Dibujar firma",
"Due Collections": "Cobros vencidos",
"Due Savings Collections": "Cobros de ahorros vencidos",
"Edit": "Editar",
+3
View File
@@ -359,6 +359,7 @@
"Change Password": "Cambiar la contraseña",
"Chargeback": "Contracargo",
"Charges Overview": "Resumen de cargos",
"Clear": "Borrar",
"Client Screen Reports": "Reportes de pantalla del cliente",
"Close": "Cerrar",
"Close Config. Wizard": "Cerrar",
@@ -424,6 +425,7 @@
"Dividends": "Dividendos",
"Download": "Descargar",
"Download CSV": "Descargar CSV",
"Draw": "Dibujar",
"Edit": "Editar",
"Edit Code": "Editar Código",
"Edit Criteria Definition": "Editar Definición de Criterios",
@@ -1017,6 +1019,7 @@
"Disable Withhold Tax": "Desactivar retención de impuestos",
"Documents": "Documentos",
"Down Payment": "Pago Inicial",
"Draw Client Signature": "Dibujar firma",
"Due Collections": "Cobros vencidos",
"Due Savings Collections": "Cobros de ahorros vencidos",
"Edit": "Editar",
+3
View File
@@ -359,6 +359,7 @@
"Change Password": "Changer le mot de passe",
"Chargeback": "Rétrofacturation",
"Charges Overview": "Aperçu des frais",
"Clear": "Effacer",
"Client Screen Reports": "Rapports d'écran client",
"Close": "Fermer",
"Close Config. Wizard": "Fermez la configuration. Magicien",
@@ -424,6 +425,7 @@
"Dividends": "Dividendes",
"Download": "Télécharger",
"Download CSV": "Télécharger CSV",
"Draw": "Dessiner",
"Edit": "Modifier",
"Edit Code": "Modifier le code",
"Edit Criteria Definition": "Modifier la définition des critères",
@@ -1018,6 +1020,7 @@
"Disable Withhold Tax": "Désactiver la retenue des impôts",
"Documents": "Documents",
"Down Payment": "Acompte",
"Draw Client Signature": "Dessiner la signature",
"Due Collections": "Recouvrements dus",
"Due Savings Collections": "Recouvrement des économies dues",
"Edit": "Modifier",
+3
View File
@@ -359,6 +359,7 @@
"Change Password": "Cambiare la password",
"Chargeback": "Riaddebito",
"Charges Overview": "Panoramica delle tariffe",
"Clear": "Cancella",
"Client Screen Reports": "Rapporti sullo schermo del cliente",
"Close": "Vicino",
"Close Config. Wizard": "Chiudi Config. Procedura guidata",
@@ -424,6 +425,7 @@
"Dividends": "Dividendi",
"Download": "Scaricamento",
"Download CSV": "Scarica CSV",
"Draw": "Disegna",
"Edit": "Modificare",
"Edit Code": "Modifica codice",
"Edit Criteria Definition": "Modifica Definizione Criteri",
@@ -1014,6 +1016,7 @@
"Disable Withhold Tax": "Disabilitare la ritenuta a trattenere l'imposta",
"Documents": "Documenti",
"Down Payment": "Acconto",
"Draw Client Signature": "Disegna firma",
"Due Collections": "Collezioni dovute",
"Due Savings Collections": "Collezioni di risparmio dovute",
"Edit": "Modificare",
+3
View File
@@ -359,6 +359,7 @@
"Change Password": "비밀번호 변경",
"Chargeback": "지불 거절",
"Charges Overview": "요금 개요",
"Clear": "지우기",
"Client Screen Reports": "클라이언트 화면 보고서",
"Close": "닫다",
"Close Config. Wizard": "구성을 닫습니다. 마법사",
@@ -424,6 +425,7 @@
"Dividends": "배당금",
"Download": "다운로드",
"Download CSV": "CSV 다운로드",
"Draw": "그리기",
"Edit": "편집하다",
"Edit Code": "코드 편집",
"Edit Criteria Definition": "기준 정의 편집",
@@ -1015,6 +1017,7 @@
"Disable Withhold Tax": "원천 징수 세금을 비활성화합니다",
"Documents": "서류",
"Down Payment": "계약금",
"Draw Client Signature": "서명 그리기",
"Due Collections": "만기 징수",
"Due Savings Collections": "미납액 징수",
"Edit": "편집하다",
+3
View File
@@ -359,6 +359,7 @@
"Change Password": "Pakeisti slaptažodį",
"Chargeback": "Mokėjimo grąžinimas",
"Charges Overview": "Mokesčių apžvalga",
"Clear": "Išvalyti",
"Client Screen Reports": "Kliento ekrano ataskaitos",
"Close": "Uždaryti",
"Close Config. Wizard": "Uždaryti konfigūraciją. burtininkas",
@@ -424,6 +425,7 @@
"Dividends": "Dividendai",
"Download": "parsisiųsti",
"Download CSV": "Atsisiųskite CSV",
"Draw": "Piešti",
"Edit": "Redaguoti",
"Edit Code": "Redaguoti kodą",
"Edit Criteria Definition": "Redaguoti kriterijų apibrėžimą",
@@ -1013,6 +1015,7 @@
"Disable Withhold Tax": "Išjungti išskaičiavimo mokestį",
"Documents": "Dokumentai",
"Down Payment": "Pradinė įmoka",
"Draw Client Signature": "Nupiešti parašą",
"Due Collections": "Sumokėtos kolekcijos",
"Due Savings Collections": "Sumokėtos santaupų kolekcijos",
"Edit": "Redaguoti",
+3
View File
@@ -359,6 +359,7 @@
"Change Password": "Mainīt paroli",
"Chargeback": "Atmaksa",
"Charges Overview": "Izmaksu pārskats",
"Clear": "Notīrīt",
"Client Screen Reports": "Klienta ekrāna pārskati",
"Close": "Aizvērt",
"Close Config. Wizard": "Aizvērt konfigurāciju. Vednis",
@@ -424,6 +425,7 @@
"Dividends": "Dividendes",
"Download": "Lejupielādēt",
"Download CSV": "Lejupielādēt CSV",
"Draw": "Zīmēt",
"Edit": "Rediģēt",
"Edit Code": "Rediģēt kodu",
"Edit Criteria Definition": "Rediģēt kritēriju definīciju",
@@ -1015,6 +1017,7 @@
"Disable Withhold Tax": "Atspējot aizturēšanas nodokli",
"Documents": "Dokumenti",
"Down Payment": "Pirmā iemaksa",
"Draw Client Signature": "Zīmēt parakstu",
"Due Collections": "Pienākamās kolekcijas",
"Due Savings Collections": "Pienākamās ietaupījumu kolekcijas",
"Edit": "Rediģēt",
+3
View File
@@ -359,6 +359,7 @@
"Change Password": "पासवर्ड परिवर्तन गर्नुहोस्",
"Chargeback": "चार्जब्याक",
"Charges Overview": "शुल्क अवलोकन",
"Clear": "मेटाउनुहोस्",
"Client Screen Reports": "ग्राहक स्क्रिन रिपोर्टहरू",
"Close": "बन्द गर्नुहोस्",
"Close Config. Wizard": "कन्फिग बन्द गर्नुहोस्। जादूगर",
@@ -424,6 +425,7 @@
"Dividends": "लाभांश",
"Download": "डाउनलोड गर्नुहोस्",
"Download CSV": "CSV डाउनलोड गर्नुहोस्",
"Draw": "कोर्नुहोस्",
"Edit": "सम्पादन गर्नुहोस्",
"Edit Code": "कोड सम्पादन गर्नुहोस्",
"Edit Criteria Definition": "मापदण्ड परिभाषा सम्पादन गर्नुहोस्",
@@ -1013,6 +1015,7 @@
"Disable Withhold Tax": "प्रयोग गर्ने कर अक्षम गर्नुहोस्",
"Documents": "कागजातहरू",
"Down Payment": "डाउन पेमेन्ट",
"Draw Client Signature": "हस्ताक्षर कोर्नुहोस्",
"Due Collections": "बाँकी संग्रहहरू",
"Due Savings Collections": "देय बचत संग्रह",
"Edit": "सम्पादन गर्नुहोस्",
+3
View File
@@ -359,6 +359,7 @@
"Change Password": "Alterar a senha",
"Chargeback": "Estorno",
"Charges Overview": "Visão geral das cobranças",
"Clear": "Limpar",
"Client Screen Reports": "Relatórios de tela do cliente",
"Close": "Fechar",
"Close Config. Wizard": "Feche a configuração. Mago",
@@ -424,6 +425,7 @@
"Dividends": "Dividendos",
"Download": "Download",
"Download CSV": "Baixar CSV",
"Draw": "Desenhar",
"Edit": "Editar",
"Edit Code": "Editar código",
"Edit Criteria Definition": "Editar Definição de Critérios",
@@ -1014,6 +1016,7 @@
"Disable Withhold Tax": "Desativar o imposto retido",
"Documents": "Documentos",
"Down Payment": "Pagamento inicial",
"Draw Client Signature": "Desenhar assinatura",
"Due Collections": "Cobranças devidas",
"Due Savings Collections": "Coleções de poupança devidas",
"Edit": "Editar",
+3
View File
@@ -359,6 +359,7 @@
"Change Password": "Badilisha neno la siri",
"Chargeback": "Urejeshaji malipo",
"Charges Overview": "Muhtasari wa Gharama",
"Clear": "Futa",
"Client Screen Reports": "Ripoti za Skrini ya Mteja",
"Close": "Funga",
"Close Config. Wizard": "Funga Usanidi. Mchawi",
@@ -424,6 +425,7 @@
"Dividends": "Gawio",
"Download": "Pakua",
"Download CSV": "Pakua CSV",
"Draw": "Chora",
"Edit": "Hariri",
"Edit Code": "Badilisha Msimbo",
"Edit Criteria Definition": "Hariri Ufafanuzi wa Vigezo",
@@ -1012,6 +1014,7 @@
"Disable Withhold Tax": "Lemaza Ushuru",
"Documents": "Nyaraka",
"Down Payment": "Malipo ya Chini",
"Draw Client Signature": "Chora saini",
"Due Collections": "Mikusanyiko Inastahili",
"Due Savings Collections": "Makusanyo ya Akiba Zinazodaiwa",
"Edit": "Hariri",