mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
Merge branch 'button-signature-zone' into 'master'
Add button unique signature zone See merge request Chill-Projet/chill-bundles!812
This commit is contained in:
commit
8ca377d5d4
6
.changes/unreleased/Feature-20250415-150324.yaml
Normal file
6
.changes/unreleased/Feature-20250415-150324.yaml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
kind: Feature
|
||||||
|
body: 'Signature: add a button to go directly to the signature zone, even if there is only one'
|
||||||
|
time: 2025-04-15T15:03:24.436112828+02:00
|
||||||
|
custom:
|
||||||
|
Issue: ""
|
||||||
|
SchemaChange: No schema change
|
@ -2,26 +2,28 @@
|
|||||||
<teleport to="body">
|
<teleport to="body">
|
||||||
<modal v-if="modalOpen" @close="modalOpen = false">
|
<modal v-if="modalOpen" @close="modalOpen = false">
|
||||||
<template v-slot:header>
|
<template v-slot:header>
|
||||||
<h2>{{ $t("signature_confirmation") }}</h2>
|
<h2>{{ trans(SIGNATURES_SIGNATURE_CONFIRMATION) }}</h2>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:body>
|
<template v-slot:body>
|
||||||
<div class="signature-modal-body text-center" v-if="loading">
|
<div class="signature-modal-body text-center" v-if="loading">
|
||||||
<p>{{ $t("electronic_signature_in_progress") }}</p>
|
<p>
|
||||||
|
{{ trans(SIGNATURES_ELECTRONIC_SIGNATURE_IN_PROGRESS) }}
|
||||||
|
</p>
|
||||||
<div class="loading">
|
<div class="loading">
|
||||||
<i
|
<i
|
||||||
class="fa fa-circle-o-notch fa-spin fa-3x"
|
class="fa fa-circle-o-notch fa-spin fa-3x"
|
||||||
:title="$t('loading')"
|
:title="trans(SIGNATURES_LOADING)"
|
||||||
></i>
|
></i>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="signature-modal-body text-center" v-else>
|
<div class="signature-modal-body text-center" v-else>
|
||||||
<p>{{ $t("you_are_going_to_sign") }}</p>
|
<p>{{ trans(SIGNATURES_YOU_ARE_GOING_TO_SIGN) }}</p>
|
||||||
<p>{{ $t("are_you_sure") }}</p>
|
<p>{{ trans(SIGNATURES_ARE_YOU_SURE) }}</p>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:footer>
|
<template v-slot:footer>
|
||||||
<button class="btn btn-action" @click.prevent="confirmSign">
|
<button class="btn btn-action" @click.prevent="confirmSign">
|
||||||
{{ $t("yes") }}
|
{{ trans(SIGNATURES_YES) }}
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
</modal>
|
</modal>
|
||||||
@ -82,28 +84,39 @@
|
|||||||
@change="toggleMultiPage"
|
@change="toggleMultiPage"
|
||||||
/>
|
/>
|
||||||
<label class="form-check-label" for="checkboxMulti">
|
<label class="form-check-label" for="checkboxMulti">
|
||||||
{{ $t("all_pages") }}
|
{{ trans(SIGNATURES_ALL_PAGES) }}
|
||||||
</label>
|
</label>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="signature.zones.length > 0"
|
v-if="signature.zones.length === 1 && signedState !== 'signed'"
|
||||||
class="col-5 p-0 text-center turnSignature"
|
class="col-5 p-0 text-center turnSignature"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
:disabled="isFirstSignatureZone"
|
class="btn btn-light btn-sm"
|
||||||
|
@click="goToSignatureZoneUnique"
|
||||||
|
>
|
||||||
|
{{ trans(SIGNATURES_GO_TO_SIGNATURE_UNIQUE) }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="signature.zones.length > 1"
|
||||||
|
class="col-5 p-0 text-center turnSignature"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
:disabled="isFirstSignatureZone()"
|
||||||
class="btn btn-light btn-sm"
|
class="btn btn-light btn-sm"
|
||||||
@click="turnSignature(-1)"
|
@click="turnSignature(-1)"
|
||||||
>
|
>
|
||||||
{{ $t("last_zone") }}
|
{{ trans(SIGNATURES_LAST_ZONE) }}
|
||||||
</button>
|
</button>
|
||||||
<span>|</span>
|
<span>|</span>
|
||||||
<button
|
<button
|
||||||
:disabled="isLastSignatureZone"
|
:disabled="isLastSignatureZone()"
|
||||||
class="btn btn-light btn-sm"
|
class="btn btn-light btn-sm"
|
||||||
@click="turnSignature(1)"
|
@click="turnSignature(1)"
|
||||||
>
|
>
|
||||||
{{ $t("next_zone") }}
|
{{ trans(SIGNATURES_NEXT_ZONE) }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="col text-end" v-if="signedState !== 'signed'">
|
<div class="col text-end" v-if="signedState !== 'signed'">
|
||||||
@ -112,9 +125,9 @@
|
|||||||
:hidden="!userSignatureZone"
|
:hidden="!userSignatureZone"
|
||||||
@click="undoSign"
|
@click="undoSign"
|
||||||
v-if="signature.zones.length > 1"
|
v-if="signature.zones.length > 1"
|
||||||
:title="$t('choose_another_signature')"
|
:title="trans(SIGNATURES_CHOOSE_ANOTHER_SIGNATURE)"
|
||||||
>
|
>
|
||||||
{{ $t("another_zone") }}
|
{{ trans(SIGNATURES_ANOTHER_ZONE) }}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="btn btn-misc btn-sm"
|
class="btn btn-misc btn-sm"
|
||||||
@ -122,7 +135,7 @@
|
|||||||
@click="undoSign"
|
@click="undoSign"
|
||||||
v-else
|
v-else
|
||||||
>
|
>
|
||||||
{{ $t("cancel") }}
|
{{ trans(SIGNATURES_CANCEL) }}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
v-if="userSignatureZone === null"
|
v-if="userSignatureZone === null"
|
||||||
@ -134,7 +147,7 @@
|
|||||||
active: canvasEvent === 'add',
|
active: canvasEvent === 'add',
|
||||||
}"
|
}"
|
||||||
@click="toggleAddZone()"
|
@click="toggleAddZone()"
|
||||||
:title="$t('add_sign_zone')"
|
:title="trans(SIGNATURES_ADD_SIGN_ZONE)"
|
||||||
>
|
>
|
||||||
<template v-if="canvasEvent === 'add'">
|
<template v-if="canvasEvent === 'add'">
|
||||||
<div
|
<div
|
||||||
@ -186,48 +199,70 @@
|
|||||||
@change="toggleMultiPage"
|
@change="toggleMultiPage"
|
||||||
/>
|
/>
|
||||||
<label class="form-check-label" for="checkboxMulti">
|
<label class="form-check-label" for="checkboxMulti">
|
||||||
{{ $t("see_all_pages") }}
|
{{ trans(SIGNATURES_SEE_ALL_PAGES) }}
|
||||||
</label>
|
</label>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="signature.zones.length > 0 && signedState !== 'signed'"
|
v-if="signature.zones.length === 1 && signedState !== 'signed'"
|
||||||
class="col-4 d-xl-none text-center turnSignature p-0"
|
class="col-4 d-xl-none text-center turnSignature p-0"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
:disabled="!hasSignatureZoneSelected"
|
|
||||||
class="btn btn-light btn-sm"
|
class="btn btn-light btn-sm"
|
||||||
@click="turnSignature(-1)"
|
@click="goToSignatureZoneUnique"
|
||||||
>
|
>
|
||||||
{{ $t("last_zone") }}
|
{{ trans(SIGNATURES_GO_TO_SIGNATURE_UNIQUE) }}
|
||||||
</button>
|
|
||||||
<span>|</span>
|
|
||||||
<button
|
|
||||||
:disabled="isLastSignatureZone"
|
|
||||||
class="btn btn-light btn-sm"
|
|
||||||
@click="turnSignature(1)"
|
|
||||||
>
|
|
||||||
{{ $t("next_zone") }}
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="signature.zones.length > 0 && signedState !== 'signed'"
|
v-if="signature.zones.length > 1 && signedState !== 'signed'"
|
||||||
class="col-4 d-none d-xl-flex p-0 text-center turnSignature"
|
class="col-4 d-xl-none text-center turnSignature p-0"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
:disabled="isFirstSignatureZone"
|
:disabled="isFirstSignatureZone()"
|
||||||
class="btn btn-light btn-sm"
|
class="btn btn-light btn-sm"
|
||||||
@click="turnSignature(-1)"
|
@click="turnSignature(-1)"
|
||||||
>
|
>
|
||||||
{{ $t("last_sign_zone") }}
|
{{ trans(SIGNATURES_LAST_ZONE) }}
|
||||||
</button>
|
</button>
|
||||||
<span>|</span>
|
<span>|</span>
|
||||||
<button
|
<button
|
||||||
:disabled="isLastSignatureZone"
|
:disabled="isLastSignatureZone()"
|
||||||
class="btn btn-light btn-sm"
|
class="btn btn-light btn-sm"
|
||||||
@click="turnSignature(1)"
|
@click="turnSignature(1)"
|
||||||
>
|
>
|
||||||
{{ $t("next_sign_zone") }}
|
{{ trans(SIGNATURES_NEXT_ZONE) }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="signature.zones.length === 1 && signedState !== 'signed'"
|
||||||
|
class="col-4 d-none d-xl-flex p-0 text-center turnSignature"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
class="btn btn-light btn-sm"
|
||||||
|
@click="goToSignatureZoneUnique"
|
||||||
|
>
|
||||||
|
{{ trans(SIGNATURES_GO_TO_SIGNATURE_UNIQUE) }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="signature.zones.length > 1 && signedState !== 'signed'"
|
||||||
|
class="col-4 d-none d-xl-flex p-0 text-center turnSignature"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
:disabled="isFirstSignatureZone()"
|
||||||
|
class="btn btn-light btn-sm"
|
||||||
|
@click="turnSignature(-1)"
|
||||||
|
>
|
||||||
|
{{ trans(SIGNATURES_LAST_SIGN_ZONE) }}
|
||||||
|
</button>
|
||||||
|
<span>|</span>
|
||||||
|
<button
|
||||||
|
:disabled="isLastSignatureZone()"
|
||||||
|
class="btn btn-light btn-sm"
|
||||||
|
@click="turnSignature(1)"
|
||||||
|
>
|
||||||
|
{{ trans(SIGNATURES_NEXT_SIGN_ZONE) }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="col text-end" v-if="signedState !== 'signed'">
|
<div class="col text-end" v-if="signedState !== 'signed'">
|
||||||
@ -237,7 +272,7 @@
|
|||||||
@click="undoSign"
|
@click="undoSign"
|
||||||
v-if="signature.zones.length > 1"
|
v-if="signature.zones.length > 1"
|
||||||
>
|
>
|
||||||
{{ $t("choose_another_signature") }}
|
{{ trans(SIGNATURES_CHOOSE_ANOTHER_SIGNATURE) }}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="btn btn-misc btn-sm"
|
class="btn btn-misc btn-sm"
|
||||||
@ -245,7 +280,7 @@
|
|||||||
@click="undoSign"
|
@click="undoSign"
|
||||||
v-else
|
v-else
|
||||||
>
|
>
|
||||||
{{ $t("cancel") }}
|
{{ trans(SIGNATURES_CANCEL) }}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
v-if="userSignatureZone === null"
|
v-if="userSignatureZone === null"
|
||||||
@ -257,13 +292,13 @@
|
|||||||
active: canvasEvent === 'add',
|
active: canvasEvent === 'add',
|
||||||
}"
|
}"
|
||||||
@click="toggleAddZone()"
|
@click="toggleAddZone()"
|
||||||
:title="$t('add_sign_zone')"
|
:title="trans(SIGNATURES_ADD_SIGN_ZONE)"
|
||||||
>
|
>
|
||||||
<template v-if="canvasEvent !== 'add'">
|
<template v-if="canvasEvent !== 'add'">
|
||||||
{{ $t("add_zone") }}
|
{{ trans(SIGNATURES_ADD_ZONE) }}
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
{{ $t("click_on_document") }}
|
{{ trans(SIGNATURES_CLICK_ON_DOCUMENT) }}
|
||||||
<div
|
<div
|
||||||
class="spinner-border spinner-border-sm"
|
class="spinner-border spinner-border-sm"
|
||||||
role="status"
|
role="status"
|
||||||
@ -297,10 +332,10 @@
|
|||||||
v-if="signedState !== 'signed'"
|
v-if="signedState !== 'signed'"
|
||||||
:href="getReturnPath()"
|
:href="getReturnPath()"
|
||||||
>
|
>
|
||||||
{{ $t("cancel") }}
|
{{ trans(SIGNATURES_CANCEL) }}
|
||||||
</a>
|
</a>
|
||||||
<a class="btn btn-misc" v-else :href="getReturnPath()">
|
<a class="btn btn-misc" v-else :href="getReturnPath()">
|
||||||
{{ $t("return") }}
|
{{ trans(SIGNATURES_RETURN) }}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="col text-end" v-if="signedState !== 'signed'">
|
<div class="col text-end" v-if="signedState !== 'signed'">
|
||||||
@ -309,7 +344,7 @@
|
|||||||
:disabled="!userSignatureZone"
|
:disabled="!userSignatureZone"
|
||||||
@click="sign"
|
@click="sign"
|
||||||
>
|
>
|
||||||
{{ $t("sign") }}
|
{{ trans(SIGNATURES_SIGN) }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-4" v-else></div>
|
<div class="col-4" v-else></div>
|
||||||
@ -318,7 +353,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, Ref, computed } from "vue";
|
import { ref, Ref } from "vue";
|
||||||
import { useToast } from "vue-toast-notification";
|
import { useToast } from "vue-toast-notification";
|
||||||
import "vue-toast-notification/dist/theme-sugar.css";
|
import "vue-toast-notification/dist/theme-sugar.css";
|
||||||
import {
|
import {
|
||||||
@ -329,13 +364,38 @@ import {
|
|||||||
SignedState,
|
SignedState,
|
||||||
ZoomLevel,
|
ZoomLevel,
|
||||||
} from "../../types";
|
} from "../../types";
|
||||||
import { makeFetch } from "../../../../../ChillMainBundle/Resources/public/lib/api/apiMethods";
|
import { makeFetch } from "ChillMainAssets/lib/api/apiMethods";
|
||||||
import * as pdfjsLib from "pdfjs-dist";
|
import * as pdfjsLib from "pdfjs-dist";
|
||||||
import {
|
import {
|
||||||
PDFDocumentProxy,
|
PDFDocumentProxy,
|
||||||
PDFPageProxy,
|
PDFPageProxy,
|
||||||
} from "pdfjs-dist/types/src/display/api";
|
} from "pdfjs-dist/types/src/display/api";
|
||||||
|
|
||||||
|
import {
|
||||||
|
SIGNATURES_YES,
|
||||||
|
SIGNATURES_ARE_YOU_SURE,
|
||||||
|
SIGNATURES_YOU_ARE_GOING_TO_SIGN,
|
||||||
|
SIGNATURES_SIGNATURE_CONFIRMATION,
|
||||||
|
SIGNATURES_SIGN,
|
||||||
|
SIGNATURES_CHOOSE_ANOTHER_SIGNATURE,
|
||||||
|
SIGNATURES_CANCEL,
|
||||||
|
SIGNATURES_LAST_SIGN_ZONE,
|
||||||
|
SIGNATURES_NEXT_SIGN_ZONE,
|
||||||
|
SIGNATURES_ADD_SIGN_ZONE,
|
||||||
|
SIGNATURES_CLICK_ON_DOCUMENT,
|
||||||
|
SIGNATURES_LAST_ZONE,
|
||||||
|
SIGNATURES_NEXT_ZONE,
|
||||||
|
SIGNATURES_ADD_ZONE,
|
||||||
|
SIGNATURES_ANOTHER_ZONE,
|
||||||
|
SIGNATURES_ELECTRONIC_SIGNATURE_IN_PROGRESS,
|
||||||
|
SIGNATURES_LOADING,
|
||||||
|
SIGNATURES_RETURN,
|
||||||
|
SIGNATURES_SEE_ALL_PAGES,
|
||||||
|
SIGNATURES_ALL_PAGES,
|
||||||
|
SIGNATURES_GO_TO_SIGNATURE_UNIQUE,
|
||||||
|
trans,
|
||||||
|
} from "translator";
|
||||||
|
|
||||||
// @ts-ignore incredible but the console.log is needed
|
// @ts-ignore incredible but the console.log is needed
|
||||||
import * as PdfWorker from "pdfjs-dist/build/pdf.worker.mjs";
|
import * as PdfWorker from "pdfjs-dist/build/pdf.worker.mjs";
|
||||||
console.log(PdfWorker);
|
console.log(PdfWorker);
|
||||||
@ -416,19 +476,15 @@ const $toast = useToast();
|
|||||||
const signature = window.signature;
|
const signature = window.signature;
|
||||||
|
|
||||||
const isFirstSignatureZone = () =>
|
const isFirstSignatureZone = () =>
|
||||||
userSignatureZone.value?.index ? userSignatureZone.value.index < 1 : false;
|
userSignatureZone.value?.index != null
|
||||||
|
? userSignatureZone.value.index < 1
|
||||||
|
: false;
|
||||||
|
|
||||||
const isLastSignatureZone = () =>
|
const isLastSignatureZone = () =>
|
||||||
userSignatureZone.value?.index
|
userSignatureZone.value?.index
|
||||||
? userSignatureZone.value.index >= signature.zones.length - 1
|
? userSignatureZone.value.index >= signature.zones.length - 1
|
||||||
: false;
|
: false;
|
||||||
|
|
||||||
/**
|
|
||||||
* Return true if the user has selected a user zone (existing on the doc or created by the user)
|
|
||||||
*/
|
|
||||||
const hasSignatureZoneSelected = computed<boolean>(
|
|
||||||
() => userSignatureZone.value !== null,
|
|
||||||
);
|
|
||||||
|
|
||||||
const setZoomLevel = async (zoomLevel: string) => {
|
const setZoomLevel = async (zoomLevel: string) => {
|
||||||
zoom.value = Number.parseFloat(zoomLevel);
|
zoom.value = Number.parseFloat(zoomLevel);
|
||||||
await resetPages();
|
await resetPages();
|
||||||
@ -600,6 +656,15 @@ const turnPage = async (upOrDown: number) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const selectZoneInCanvas = (signatureZone: SignatureZone) => {
|
||||||
|
page.value = signatureZone.PDFPage.index + 1;
|
||||||
|
const canvas = getCanvas(signatureZone.PDFPage.index + 1);
|
||||||
|
selectZone(signatureZone, canvas);
|
||||||
|
canvas.scrollIntoView();
|
||||||
|
};
|
||||||
|
|
||||||
|
const goToSignatureZoneUnique = () => selectZoneInCanvas(signature.zones[0]);
|
||||||
|
|
||||||
const turnSignature = async (upOrDown: number) => {
|
const turnSignature = async (upOrDown: number) => {
|
||||||
let zoneIndex = userSignatureZone.value?.index ?? -1;
|
let zoneIndex = userSignatureZone.value?.index ?? -1;
|
||||||
if (zoneIndex < -1) {
|
if (zoneIndex < -1) {
|
||||||
@ -612,10 +677,7 @@ const turnSignature = async (upOrDown: number) => {
|
|||||||
}
|
}
|
||||||
let currentZone = signature.zones[zoneIndex];
|
let currentZone = signature.zones[zoneIndex];
|
||||||
if (currentZone) {
|
if (currentZone) {
|
||||||
page.value = currentZone.PDFPage.index + 1;
|
selectZoneInCanvas(currentZone);
|
||||||
const canvas = getCanvas(currentZone.PDFPage.index + 1);
|
|
||||||
selectZone(currentZone, canvas);
|
|
||||||
canvas.scrollIntoView();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -99,3 +99,30 @@ CHILL_ACCOMPANYING_COURSE_DOCUMENT_UPDATE: Modifier un document
|
|||||||
entity_display_title:
|
entity_display_title:
|
||||||
Document (n°%doc%): "Document (n°%doc%)"
|
Document (n°%doc%): "Document (n°%doc%)"
|
||||||
Doc for evaluation (n°%eval%): Document de l'évaluation n°%eval%
|
Doc for evaluation (n°%eval%): Document de l'évaluation n°%eval%
|
||||||
|
|
||||||
|
|
||||||
|
# SIGNATURES
|
||||||
|
|
||||||
|
signatures:
|
||||||
|
yes: Oui
|
||||||
|
are_you_sure: Êtes-vous sûr·e?
|
||||||
|
you_are_going_to_sign: Vous allez signer le document
|
||||||
|
signature_confirmation: Confirmation de la signature
|
||||||
|
sign: Signer
|
||||||
|
choose_another_signature: Choisir une autre zone
|
||||||
|
cancel: Annuler
|
||||||
|
last_sign_zone: Zone de signature précédente
|
||||||
|
next_sign_zone: Zone de signature suivante
|
||||||
|
add_sign_zone: Ajouter une zone de signature
|
||||||
|
click_on_document: Cliquer sur le document
|
||||||
|
last_zone: Zone précédente
|
||||||
|
next_zone: Zone suivante
|
||||||
|
add_zone: Ajouter une zone
|
||||||
|
another_zone: Autre zone
|
||||||
|
electronic_signature_in_progress: Signature électronique en cours...
|
||||||
|
loading: Chargement...
|
||||||
|
remove_sign_zone: Enlever la zone
|
||||||
|
return: Retour
|
||||||
|
see_all_pages: Voir toutes les pages
|
||||||
|
all_pages: Toutes les pages
|
||||||
|
go_to_signature_unique: Aller à la zone de signature
|
||||||
|
Loading…
x
Reference in New Issue
Block a user