diff --git a/lang/en.json b/lang/en.json index 7e266ced5f84aa7731b87b2e5b09ce0d84781eb4..ffe0f6de6801cbe74635aa1aa55e505a03f93efe 100755 --- a/lang/en.json +++ b/lang/en.json @@ -633,6 +633,7 @@ "showPassword": "Show password", "hidePassword": "Hide password", "cannotSetSignature": "You cannot pre-position a signature for a user with the annotator role", - "resumeOriginalDoc": "Warning ! The return document action will use the original document" + "resumeOriginalDoc": "Warning ! The return document action will use the original document", + "emptySignList": "No stamp available" } } \ No newline at end of file diff --git a/lang/fr.json b/lang/fr.json index a60ace8d109dc9ebb45a90bc61e499dbc595c0a0..83131940527e731896bcc593e89e55a269c31a05 100755 --- a/lang/fr.json +++ b/lang/fr.json @@ -632,6 +632,7 @@ "showPassword": "Afficher le mot de passe", "hidePassword": "Masquer le mot de passe", "cannotSetSignature": "Vous ne pouvez pas pré-positionner une signature pour un utilisateur avec le rôle annotateur", - "resumeOriginalDoc": "Attention ! L'action renvoi de document reprend le document original" + "resumeOriginalDoc": "Attention ! L'action renvoi de document reprend le document original", + "emptySignList": "Aucune griffe disponible" } } diff --git a/src/frontend/app/pad/pad.component.html b/src/frontend/app/pad/pad.component.html index 8737c4dd958337a9d7f8d17220aa17b8a6522c26..f6d209eb0fdf0afd4850ff7f09db16d6dbe7430b 100755 --- a/src/frontend/app/pad/pad.component.html +++ b/src/frontend/app/pad/pad.component.html @@ -27,7 +27,7 @@ <ion-content #padContent> <article class="pad"> <section class="pad-draw"> - <signature-pad #signaturePad class="padContent" [options]="signaturePadOptions" (onEndEvent)="drawComplete()"></signature-pad> + <signature-pad #signaturePad class="padContent" [options]="signaturePadOptions" (onEndEvent)="drawComplete()" style="margin-top: 10px;"></signature-pad> </section> <div class="draw"></div> </article> diff --git a/src/frontend/app/profile/profile.component.html b/src/frontend/app/profile/profile.component.html index d1e777d9a3c1383b2e50ba2824e316fbdef03efd..586f34c19421ad9ff23ce011087bafc0f52f42cd 100644 --- a/src/frontend/app/profile/profile.component.html +++ b/src/frontend/app/profile/profile.component.html @@ -15,6 +15,10 @@ <ion-label>{{'lang.informations' | translate}}</ion-label> <ion-icon name="information-circle"></ion-icon> </ion-segment-button> + <ion-segment-button value="signatures"> + <ion-label>{{'lang.signatures' | translate}}</ion-label> + <ion-icon name="pencil-outline"></ion-icon> + </ion-segment-button> <ion-segment-button value="pref"> <ion-label>{{'lang.preferences' | translate}}</ion-label> <ion-icon name="brush-outline"></ion-icon> @@ -253,6 +257,9 @@ <ion-label color="primary" style="font-style: italic;">{{ 'lang.noScheduledNotif' | translate }}</ion-label> </ion-item> </ng-container> + <ng-container *ngIf="currentTool === 'signatures'"> + <app-signatures [target]="'profile'"></app-signatures> + </ng-container> </ion-content> </form> <ion-footer class="ion-no-border" *ngIf="['info','pref', 'scheduledNotifications'].indexOf(currentTool) > -1"> diff --git a/src/frontend/app/sidebar/sidebar.component.ts b/src/frontend/app/sidebar/sidebar.component.ts index 1aa1554c4a2aa0494299e0e6321fa69a065e05ae..e5d662cce750f4c5858709c47cfdd2e86146fe98 100755 --- a/src/frontend/app/sidebar/sidebar.component.ts +++ b/src/frontend/app/sidebar/sidebar.component.ts @@ -78,7 +78,7 @@ export class SidebarComponent implements OnInit, AfterViewInit { async openProfile() { const modal = await this.modalController.create({ component: ProfileComponent, - cssClass: 'myClass' + cssClass: 'profileCss' }); await modal.present(); } diff --git a/src/frontend/app/signatures/signatures.component.html b/src/frontend/app/signatures/signatures.component.html index 9ea896efe70b524b28f75b7c703a9369d39b27d5..c8901d123ea2c4a30cb74481cc4042d0aa3f43ed 100755 --- a/src/frontend/app/signatures/signatures.component.html +++ b/src/frontend/app/signatures/signatures.component.html @@ -1,4 +1,4 @@ -<ion-header [translucent]="true"> +<ion-header *ngIf="target === 'document'" [translucent]="true"> <ion-toolbar color="primary"> <ion-title>{{(!signaturesService.stampLock ? 'lang.signatures' : 'lang.certifiedDocument') | translate}} <small class="secondary" *ngIf="signPosMode">{{this.currentWorflow.signaturePositions.length}} {{'lang.prePositionings' | translate}}</small></ion-title> <ion-buttons slot="end"> @@ -10,15 +10,18 @@ </ion-header> <ion-content (wheel)="!signaturesService.stampLock ? scroll($event): null"> <ng-container *ngIf="!signaturesService.stampLock; else elseCertified"> - <ion-slides *ngIf="!loading" pager="true" [options]="slideOpts" #slides> + <ion-slides *ngIf="!loading" pager="true" [options]="slideOpts" #slides [class.hideSwiper]="signaturesList.length === 0"> + <ion-item *ngIf="signaturesList.length === 0" class="emptySignList" lines="none"> + <ion-label>{{'lang.emptySignList' | translate}}</ion-label> + </ion-item> <ion-slide *ngFor="let slide of signaturesList" style="display: grid;grid-template-columns: repeat(2, 1fr);"> <div style="display: contents;"> <ion-card *ngFor="let sign of slide; let i=index" class="sign-image"> - <img id="imgSign_{{i}}" (click)="selectSignature(sign);" [src]="sanitization.bypassSecurityTrustUrl('data:image/png;base64,' + sign.encodedSignature)" + <img id="imgSign_{{i}}" (click)="target === 'document' ? selectSignature(sign) : '';" [src]="sanitization.bypassSecurityTrustUrl('data:image/png;base64,' + sign.encodedSignature)" style="width: 190px;cursor: pointer;"> - <ion-toolbar style="position: absolute;top: 0px;"> + <ion-toolbar style="position: absolute;top: 0px;" color="default"> <ion-label color="secondary" *ngIf="sign.substituted">{{'lang.substitutedSignature' | translate}}</ion-label> - <ion-buttons slot="start"> + <ion-buttons *ngIf="target === 'document'" slot="start"> <ion-button size="small" color="primary" (click)="selectSignature(sign);" [title]="'lang.selectSignature' | translate"> <ion-icon slot="icon-only" name="arrow-up-circle-outline"></ion-icon> </ion-button> @@ -38,7 +41,7 @@ <ion-icon name="chevron-up-outline"></ion-icon> </ion-fab-button> <ion-fab-list side="top"> - <ion-fab-button color="light" [title]="'lang.addNewDate' | translate" (click)="addNewDate()"> + <ion-fab-button *ngIf="target === 'document'" color="light" [title]="'lang.addNewDate' | translate" (click)="addNewDate()"> <ion-icon name="calendar-outline"></ion-icon> </ion-fab-button> <ion-fab-button color="light" [title]="'lang.importNewSignature' | translate" (click)="uploadFile.click()"> diff --git a/src/frontend/app/signatures/signatures.component.scss b/src/frontend/app/signatures/signatures.component.scss index 7910566c66a13df1da11436b00a3bcc71e323752..a10f14cd516a204c0ffdd6dda1a4d19c9d5138b2 100644 --- a/src/frontend/app/signatures/signatures.component.scss +++ b/src/frontend/app/signatures/signatures.component.scss @@ -103,4 +103,16 @@ font-size: 30px; color: var(--ion-color-medium); } +} + +.emptySignList { + text-align: center; + display: inherit; + height: 100% !important; + font-size: 30px; + opacity: 0.5; +} + +.hideSwiper { + --bullet-background-active: none; } \ No newline at end of file diff --git a/src/frontend/app/signatures/signatures.component.ts b/src/frontend/app/signatures/signatures.component.ts index 58f6e5b34718a76f5f2faa73573abcbd7317746b..4923d8b645c5f21aaddad177f1d283446ed0116d 100755 --- a/src/frontend/app/signatures/signatures.component.ts +++ b/src/frontend/app/signatures/signatures.component.ts @@ -8,8 +8,9 @@ import { NotificationService } from '../service/notification.service'; import { TranslateService } from '@ngx-translate/core'; import { AuthService } from '../service/auth.service'; import { LocalStorageService } from '../service/local-storage.service'; -import { IonSlides, ModalController } from '@ionic/angular'; +import { AlertController, IonSlides, ModalController } from '@ionic/angular'; import { SignaturePadPageComponent } from '../pad/pad.component'; +import { FunctionsService } from '../service/functions.service'; @Component({ selector: 'app-signatures', @@ -20,6 +21,7 @@ export class SignaturesComponent implements OnInit { @Input() currentWorflow: any; @Input() content: any; + @Input() target: 'document' | 'profile' = 'document'; @ViewChild('slides', { static: false }) slides: IonSlides; @@ -42,16 +44,19 @@ export class SignaturesComponent implements OnInit { signatureWidth: number; signatureScaling: any; - constructor(private translate: TranslateService, + constructor( public http: HttpClient, public signaturesService: SignaturesContentService, - private bottomSheetRef: MatBottomSheet, - private sanitization: DomSanitizer, public notificationService: NotificationService, public authService: AuthService, + public modalController: ModalController, + private translate: TranslateService, private localStorage: LocalStorageService, + public functions: FunctionsService, + public alertController: AlertController, + private bottomSheetRef: MatBottomSheet, + private sanitization: DomSanitizer, private renderer: Renderer2, - public modalController: ModalController ) { } @@ -74,9 +79,14 @@ export class SignaturesComponent implements OnInit { } ngOnInit() { + this.signaturesService.stampLock = false; this.initSignatures(); - this.signPosMode = this.currentWorflow.signaturePositions.length > 0 && this.emptySigns(); - this.getImgDimensions(this.content); + if (this.target === 'document') { + this.signPosMode = this.currentWorflow.signaturePositions.length > 0 && this.emptySigns(); + this.getImgDimensions(this.content); + } else { + this.loading = false; + } } initSignatures() { @@ -104,9 +114,10 @@ export class SignaturesComponent implements OnInit { } async openSignatures() { + const cssClass: string = this.target === 'profile' ? 'profileCss' : 'my-custom-class'; const modal = await this.modalController.create({ component: SignaturePadPageComponent, - cssClass: 'my-custom-class' + cssClass: cssClass }); await modal.present(); const { data } = await modal.onWillDismiss(); @@ -250,19 +261,35 @@ export class SignaturesComponent implements OnInit { this.localStorage.save(this.signaturesService.mainDocumentId.toString(), JSON.stringify({ 'date': this.signaturesService.datesContent, 'sign': this.signaturesService.signaturesContent, 'note': this.signaturesService.notesContent })); } - removeSignature(signature: any) { - const r = confirm(this.translate.instant('lang.wantDeleteSignature')); - - if (r) { - this.http.delete('../rest/users/' + this.authService.user.id + '/signatures/' + signature.id) - .subscribe(() => { - this.signaturesService.signaturesList = this.signaturesService.signaturesList.filter((element) => element.id !== signature.id); - this.notificationService.success('lang.signatureDeleted'); - this.initSignatures(); - }, (err: any) => { - this.notificationService.error(err.error.errors); - }); - } + async removeSignature(signature: any) { + const alert = await this.alertController.create({ + // cssClass: 'custom-alert-danger', + header: this.translate.instant('lang.wantDeleteSignature'), + buttons: [ + { + text: this.translate.instant('lang.no'), + role: 'cancel', + cssClass: 'secondary', + handler: () => { } + }, + { + text: this.translate.instant('lang.yes'), + handler: () => { + this.http.delete('../rest/users/' + this.authService.user.id + '/signatures/' + signature.id) + .subscribe(() => { + this.signaturesService.signaturesList = this.signaturesService.signaturesList.filter((element) => element.id !== signature.id); + this.notificationService.success('lang.signatureDeleted'); + this.initSignatures(); + }, (err: any) => { + this.notificationService.error(err.error.errors); + }); + } + } + ] + }); + + await alert.present(); + } toggleAllPage() { diff --git a/src/frontend/core/global.scss b/src/frontend/core/global.scss index 4c6b02788a75906bffe7d598b813d785536033cd..467941c709a51733b0a1580509400c40cb54f5e8 100644 --- a/src/frontend/core/global.scss +++ b/src/frontend/core/global.scss @@ -80,6 +80,11 @@ input:read-only { --height: 100%; } +.profileCss { + --width: 40%; + --height: 65%; +} + ion-icon { pointer-events: none; }