mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
Merge branch '318-signature-vue-app-show-full-doc' into 'master'
Resolve "[App de signature] Pouvoir voir le document en continu (toutes les pages ensemble)" Closes #318 See merge request Chill-Projet/chill-bundles!761
This commit is contained in:
commit
f5c1b5cf8a
5
.changes/unreleased/Feature-20241205-172341.yaml
Normal file
5
.changes/unreleased/Feature-20241205-172341.yaml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
kind: Feature
|
||||||
|
body: Show all the pages of the documents in the signature app
|
||||||
|
time: 2024-12-05T17:23:41.866322287+01:00
|
||||||
|
custom:
|
||||||
|
Issue: "318"
|
11
config/packages/chill_workflow_signature_documents.yaml
Normal file
11
config/packages/chill_workflow_signature_documents.yaml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
chill_main:
|
||||||
|
workflow_signature:
|
||||||
|
base_signer:
|
||||||
|
document_kinds:
|
||||||
|
- { key: id_card, labels: [ { lang: fr, label: "Carte d'identité" } ] }
|
||||||
|
- { key: passport, labels: [ { lang: fr, label: "Passeport" } ] }
|
||||||
|
- { key: drivers_license, labels: [ { lang: fr, label: "Permis de conduire" } ] }
|
||||||
|
- { key: visa_long_stay, labels: [ { lang: fr, label: "Visa de long séjour" } ] }
|
||||||
|
- { key: resident_permit, labels: [ { lang: fr, label: "Carte de séjour" } ] }
|
||||||
|
- { key: residency_card, labels: [ { lang: fr, label: "Carte de résident" } ] }
|
||||||
|
- { key: provisionary_residency_permit, labels: [ { lang: fr, label: "Autorisation provisoire de séjour" } ] }
|
@ -26,9 +26,9 @@
|
|||||||
</template>
|
</template>
|
||||||
</modal>
|
</modal>
|
||||||
</teleport>
|
</teleport>
|
||||||
<div class="col-12 m-auto">
|
<div class="col-12 m-auto sticky-top">
|
||||||
<div class="row justify-content-center border-bottom pdf-tools d-md-none">
|
<div class="row justify-content-center border-bottom pdf-tools d-md-none">
|
||||||
<div class="col text-center turn-page">
|
<div class="col-5 text-center turn-page">
|
||||||
<select
|
<select
|
||||||
class="form-select form-select-sm"
|
class="form-select form-select-sm"
|
||||||
id="zoomSelect"
|
id="zoomSelect"
|
||||||
@ -57,9 +57,35 @@
|
|||||||
❯
|
❯
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
|
<template v-if="pageCount > 1">
|
||||||
|
<button
|
||||||
|
class="btn btn-light btn-xs p-1"
|
||||||
|
:disabled="page <= 1"
|
||||||
|
@click="turnPage(-1)"
|
||||||
|
>
|
||||||
|
❮
|
||||||
|
</button>
|
||||||
|
<span>{{ page }}/{{ pageCount }}</span>
|
||||||
|
<button
|
||||||
|
class="btn btn-light btn-xs p-1"
|
||||||
|
:disabled="page >= pageCount"
|
||||||
|
@click="turnPage(1)"
|
||||||
|
>
|
||||||
|
❯
|
||||||
|
</button>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
id="checkboxMulti"
|
||||||
|
v-model="multiPage"
|
||||||
|
@change="toggleMultiPage"
|
||||||
|
/>
|
||||||
|
<label class="form-check-label" for="checkboxMulti">
|
||||||
|
{{ $t("all_pages") }}
|
||||||
|
</label>
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="signature.zones.length > 1"
|
v-if="signature.zones.length > 0"
|
||||||
class="col-5 p-0 text-center turnSignature"
|
class="col-5 p-0 text-center turnSignature"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
@ -120,7 +146,7 @@
|
|||||||
<div
|
<div
|
||||||
class="row justify-content-center border-bottom pdf-tools d-none d-md-flex"
|
class="row justify-content-center border-bottom pdf-tools d-none d-md-flex"
|
||||||
>
|
>
|
||||||
<div class="col-3 text-center turn-page ps-3">
|
<div class="col-5 text-center turn-page ps-3">
|
||||||
<select
|
<select
|
||||||
class="form-select form-select-sm"
|
class="form-select form-select-sm"
|
||||||
id="zoomSelect"
|
id="zoomSelect"
|
||||||
@ -148,10 +174,19 @@
|
|||||||
>
|
>
|
||||||
❯
|
❯
|
||||||
</button>
|
</button>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
id="checkboxMulti"
|
||||||
|
v-model="multiPage"
|
||||||
|
@change="toggleMultiPage"
|
||||||
|
/>
|
||||||
|
<label class="form-check-label" for="checkboxMulti">
|
||||||
|
{{ $t("see_all_pages") }}
|
||||||
|
</label>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="signature.zones.length > 1 && signedState !== 'signed'"
|
v-if="signature.zones.length > 0 && 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
|
||||||
@ -171,7 +206,7 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="signature.zones.length > 1 && signedState !== 'signed'"
|
v-if="signature.zones.length > 0 && signedState !== 'signed'"
|
||||||
class="col-4 d-none d-xl-flex p-0 text-center turnSignature"
|
class="col-4 d-none d-xl-flex p-0 text-center turnSignature"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
@ -233,12 +268,19 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
v-if="multiPage"
|
||||||
|
class="col-xs-12 col-md-12 col-lg-9 m-auto my-5 text-center d-flex flex-column"
|
||||||
|
:class="{ onAddZone: canvasEvent === 'add' }"
|
||||||
|
>
|
||||||
|
<canvas v-for="p in pageCount" :key="p" :id="`canvas-${p}`"></canvas>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-else
|
||||||
class="col-xs-12 col-md-12 col-lg-9 m-auto my-5 text-center"
|
class="col-xs-12 col-md-12 col-lg-9 m-auto my-5 text-center"
|
||||||
:class="{ onAddZone: canvasEvent === 'add' }"
|
:class="{ onAddZone: canvasEvent === 'add' }"
|
||||||
>
|
>
|
||||||
<canvas class="m-auto" id="canvas"></canvas>
|
<canvas class="m-auto" id="canvas"></canvas>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-xs-12 col-md-12 col-lg-9 m-auto p-4" id="action-buttons">
|
<div class="col-xs-12 col-md-12 col-lg-9 m-auto p-4" id="action-buttons">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col d-flex">
|
<div class="col d-flex">
|
||||||
@ -298,6 +340,7 @@ import {download_and_decrypt_doc, download_doc_as_pdf} from "../StoredObjectButt
|
|||||||
|
|
||||||
pdfjsLib.GlobalWorkerOptions.workerSrc = "pdfjs-dist/build/pdf.worker.mjs";
|
pdfjsLib.GlobalWorkerOptions.workerSrc = "pdfjs-dist/build/pdf.worker.mjs";
|
||||||
|
|
||||||
|
const multiPage: Ref<boolean> = ref(true);
|
||||||
const modalOpen: Ref<boolean> = ref(false);
|
const modalOpen: Ref<boolean> = ref(false);
|
||||||
const loading: Ref<boolean> = ref(false);
|
const loading: Ref<boolean> = ref(false);
|
||||||
const adding: Ref<boolean> = ref(false);
|
const adding: Ref<boolean> = ref(false);
|
||||||
@ -364,23 +407,37 @@ const $toast = useToast();
|
|||||||
|
|
||||||
const signature = window.signature;
|
const signature = window.signature;
|
||||||
|
|
||||||
const setZoomLevel = (zoomLevel: string) => {
|
const setZoomLevel = async (zoomLevel: string) => {
|
||||||
zoom.value = Number.parseFloat(zoomLevel);
|
zoom.value = Number.parseFloat(zoomLevel);
|
||||||
setPage(page.value);
|
await resetPages();
|
||||||
setTimeout(() => drawAllZones(page.value), 200);
|
setTimeout(drawAllZones, 200);
|
||||||
};
|
};
|
||||||
|
|
||||||
const mountPdf = async (doc: ArrayBuffer) => {
|
const mountPdf = async (doc: ArrayBuffer) => {
|
||||||
const loadingTask = pdfjsLib.getDocument(doc);
|
const loadingTask = pdfjsLib.getDocument(doc);
|
||||||
pdf = await loadingTask.promise;
|
pdf = await loadingTask.promise;
|
||||||
pageCount.value = pdf.numPages;
|
pageCount.value = pdf.numPages;
|
||||||
await setPage(page.value);
|
if (multiPage.value) {
|
||||||
|
await setAllPages();
|
||||||
|
} else {
|
||||||
|
await setPage(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getCanvas = (page: number) =>
|
||||||
|
multiPage.value
|
||||||
|
? (document.getElementById(`canvas-${page}`) as HTMLCanvasElement)
|
||||||
|
: (document.querySelectorAll("canvas")[0] as HTMLCanvasElement);
|
||||||
|
|
||||||
|
const getCanvasId = (canvas: HTMLCanvasElement) => {
|
||||||
|
const number = canvas.id.split("-").pop();
|
||||||
|
return number ? parseInt(number) : 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getRenderContext = (pdfPage: PDFPageProxy) => {
|
const getRenderContext = (pdfPage: PDFPageProxy) => {
|
||||||
const scale = 1 * zoom.value;
|
const scale = 1 * zoom.value;
|
||||||
const viewport = pdfPage.getViewport({ scale });
|
const viewport = pdfPage.getViewport({ scale });
|
||||||
const canvas = document.querySelectorAll("canvas")[0] as HTMLCanvasElement;
|
const canvas = getCanvas(pdfPage.pageNumber);
|
||||||
const context = canvas.getContext("2d") as CanvasRenderingContext2D;
|
const context = canvas.getContext("2d") as CanvasRenderingContext2D;
|
||||||
canvas.height = viewport.height;
|
canvas.height = viewport.height;
|
||||||
canvas.width = viewport.width;
|
canvas.width = viewport.width;
|
||||||
@ -391,6 +448,9 @@ const getRenderContext = (pdfPage: PDFPageProxy) => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const setAllPages = async () =>
|
||||||
|
Array.from(Array(pageCount.value).keys()).map((p) => setPage(p + 1));
|
||||||
|
|
||||||
const setPage = async (page: number) => {
|
const setPage = async (page: number) => {
|
||||||
const pdfPage = await pdf.getPage(page);
|
const pdfPage = await pdf.getPage(page);
|
||||||
const renderContext = getRenderContext(pdfPage);
|
const renderContext = getRenderContext(pdfPage);
|
||||||
@ -412,10 +472,34 @@ async function downloadAndOpen(): Promise<Blob> {
|
|||||||
return raw;
|
return raw;
|
||||||
}
|
}
|
||||||
|
|
||||||
const initPdf = () => {
|
const addCanvasEvents = () => {
|
||||||
|
if (multiPage.value) {
|
||||||
|
Array.from(Array(pageCount.value).keys()).map((p) => {
|
||||||
|
const canvas = getCanvas(p + 1);
|
||||||
|
canvas.addEventListener(
|
||||||
|
"pointerup",
|
||||||
|
(e) => canvasClick(e, canvas),
|
||||||
|
false
|
||||||
|
);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
const canvas = document.querySelectorAll("canvas")[0] as HTMLCanvasElement;
|
const canvas = document.querySelectorAll("canvas")[0] as HTMLCanvasElement;
|
||||||
canvas.addEventListener("pointerup", canvasClick, false);
|
canvas.addEventListener("pointerup", (e) => canvasClick(e, canvas), false);
|
||||||
setTimeout(() => drawAllZones(page.value), 800);
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const initPdf = () => {
|
||||||
|
addCanvasEvents();
|
||||||
|
setTimeout(drawAllZones, 800);
|
||||||
|
};
|
||||||
|
|
||||||
|
const resetPages = () =>
|
||||||
|
multiPage.value ? setAllPages() : setPage(page.value);
|
||||||
|
|
||||||
|
const toggleMultiPage = async () => {
|
||||||
|
await resetPages();
|
||||||
|
setTimeout(drawAllZones, 200);
|
||||||
|
addCanvasEvents();
|
||||||
};
|
};
|
||||||
|
|
||||||
const scaleXToCanvas = (x: number, canvasWidth: number, PDFWidth: number) =>
|
const scaleXToCanvas = (x: number, canvasWidth: number, PDFWidth: number) =>
|
||||||
@ -427,35 +511,36 @@ const scaleYToCanvas = (h: number, canvasHeight: number, PDFHeight: number) =>
|
|||||||
const hitSignature = (
|
const hitSignature = (
|
||||||
zone: SignatureZone,
|
zone: SignatureZone,
|
||||||
xy: number[],
|
xy: number[],
|
||||||
canvasWidth: number,
|
canvas: HTMLCanvasElement
|
||||||
canvasHeight: number
|
|
||||||
) =>
|
) =>
|
||||||
scaleXToCanvas(zone.x, canvasWidth, zone.PDFPage.width) < xy[0] &&
|
scaleXToCanvas(zone.x, canvas.width, zone.PDFPage.width) < xy[0] &&
|
||||||
xy[0] <
|
xy[0] <
|
||||||
scaleXToCanvas(zone.x + zone.width, canvasWidth, zone.PDFPage.width) &&
|
scaleXToCanvas(zone.x + zone.width, canvas.width, zone.PDFPage.width) &&
|
||||||
zone.PDFPage.height * zoom.value -
|
zone.PDFPage.height * zoom.value -
|
||||||
scaleYToCanvas(zone.y, canvasHeight, zone.PDFPage.height) <
|
scaleYToCanvas(zone.y, canvas.height, zone.PDFPage.height) <
|
||||||
xy[1] &&
|
xy[1] &&
|
||||||
xy[1] <
|
xy[1] <
|
||||||
scaleYToCanvas(zone.height - zone.y, canvasHeight, zone.PDFPage.height) +
|
scaleYToCanvas(zone.height - zone.y, canvas.height, zone.PDFPage.height) +
|
||||||
zone.PDFPage.height * zoom.value;
|
zone.PDFPage.height * zoom.value;
|
||||||
|
|
||||||
const selectZone = (z: SignatureZone, canvas: HTMLCanvasElement) => {
|
const selectZone = async (z: SignatureZone, canvas: HTMLCanvasElement) => {
|
||||||
userSignatureZone.value = z;
|
userSignatureZone.value = z;
|
||||||
const ctx = canvas.getContext("2d");
|
const ctx = canvas.getContext("2d");
|
||||||
if (ctx) {
|
if (ctx) {
|
||||||
setPage(page.value);
|
await resetPages();
|
||||||
setTimeout(() => drawAllZones(page.value), 200);
|
setTimeout(drawAllZones, 200);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const selectZoneEvent = (e: PointerEvent, canvas: HTMLCanvasElement) =>
|
const selectZoneEvent = (e: PointerEvent, canvas: HTMLCanvasElement) =>
|
||||||
signature.zones
|
signature.zones
|
||||||
.filter((z) => z.PDFPage.index + 1 === page.value)
|
.filter(
|
||||||
|
(z) =>
|
||||||
|
(z.PDFPage.index + 1 === getCanvasId(canvas) && multiPage.value) ||
|
||||||
|
(z.PDFPage.index + 1 === page.value && !multiPage.value)
|
||||||
|
)
|
||||||
.map((z) => {
|
.map((z) => {
|
||||||
if (
|
if (hitSignature(z, [e.offsetX, e.offsetY], canvas)) {
|
||||||
hitSignature(z, [e.offsetX, e.offsetY], canvas.width, canvas.height)
|
|
||||||
) {
|
|
||||||
if (userSignatureZone.value === null) {
|
if (userSignatureZone.value === null) {
|
||||||
selectZone(z, canvas);
|
selectZone(z, canvas);
|
||||||
} else {
|
} else {
|
||||||
@ -466,18 +551,20 @@ const selectZoneEvent = (e: PointerEvent, canvas: HTMLCanvasElement) =>
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const canvasClick = (e: PointerEvent) => {
|
const canvasClick = (e: PointerEvent, canvas: HTMLCanvasElement) =>
|
||||||
const canvas = document.querySelectorAll("canvas")[0] as HTMLCanvasElement;
|
|
||||||
canvasEvent.value === "select"
|
canvasEvent.value === "select"
|
||||||
? selectZoneEvent(e, canvas)
|
? selectZoneEvent(e, canvas)
|
||||||
: addZoneEvent(e, canvas);
|
: addZoneEvent(e, canvas);
|
||||||
};
|
|
||||||
|
|
||||||
const turnPage = async (upOrDown: number) => {
|
const turnPage = async (upOrDown: number) => {
|
||||||
//userSignatureZone.value = null; // desactivate the reset of the zone when turning page
|
|
||||||
page.value = page.value + upOrDown;
|
page.value = page.value + upOrDown;
|
||||||
|
if (multiPage.value) {
|
||||||
|
const canvas = getCanvas(page.value);
|
||||||
|
canvas.scrollIntoView();
|
||||||
|
} else {
|
||||||
await setPage(page.value);
|
await setPage(page.value);
|
||||||
setTimeout(() => drawAllZones(page.value), 200);
|
setTimeout(drawAllZones, 200);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const turnSignature = async (upOrDown: number) => {
|
const turnSignature = async (upOrDown: number) => {
|
||||||
@ -493,9 +580,9 @@ 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;
|
page.value = currentZone.PDFPage.index + 1;
|
||||||
userSignatureZone.value = currentZone;
|
const canvas = getCanvas(currentZone.PDFPage.index + 1);
|
||||||
const canvas = document.querySelectorAll("canvas")[0];
|
|
||||||
selectZone(currentZone, canvas);
|
selectZone(currentZone, canvas);
|
||||||
|
canvas.scrollIntoView();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -540,13 +627,18 @@ const drawZone = (
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const drawAllZones = (page: number) => {
|
const drawAllZones = () => {
|
||||||
const canvas = document.querySelectorAll("canvas")[0];
|
if (signedState.value !== "signed") {
|
||||||
const ctx = canvas.getContext("2d");
|
|
||||||
if (ctx && signedState.value !== "signed") {
|
|
||||||
signature.zones
|
signature.zones
|
||||||
.filter((z) => z.PDFPage.index + 1 === page)
|
.filter(
|
||||||
|
(z) =>
|
||||||
|
multiPage.value ||
|
||||||
|
(z.PDFPage.index + 1 === page.value && !multiPage.value)
|
||||||
|
)
|
||||||
.map((z) => {
|
.map((z) => {
|
||||||
|
const canvas = getCanvas(z.PDFPage.index + 1);
|
||||||
|
const ctx = canvas.getContext("2d");
|
||||||
|
if (ctx) {
|
||||||
if (userSignatureZone.value) {
|
if (userSignatureZone.value) {
|
||||||
if (userSignatureZone.value?.index === z.index) {
|
if (userSignatureZone.value?.index === z.index) {
|
||||||
drawZone(z, ctx, canvas.width, canvas.height);
|
drawZone(z, ctx, canvas.width, canvas.height);
|
||||||
@ -554,6 +646,7 @@ const drawAllZones = (page: number) => {
|
|||||||
} else {
|
} else {
|
||||||
drawZone(z, ctx, canvas.width, canvas.height);
|
drawZone(z, ctx, canvas.width, canvas.height);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -638,8 +731,8 @@ const confirmSign = () => {
|
|||||||
|
|
||||||
const undoSign = async () => {
|
const undoSign = async () => {
|
||||||
signature.zones = signature.zones.filter((z) => z.index !== null);
|
signature.zones = signature.zones.filter((z) => z.index !== null);
|
||||||
await setPage(page.value);
|
await resetPages();
|
||||||
setTimeout(() => drawAllZones(page.value), 200);
|
setTimeout(drawAllZones, 200);
|
||||||
userSignatureZone.value = null;
|
userSignatureZone.value = null;
|
||||||
adding.value = false;
|
adding.value = false;
|
||||||
canvasEvent.value = "select";
|
canvasEvent.value = "select";
|
||||||
@ -671,7 +764,7 @@ const addZoneEvent = async (e: PointerEvent, canvas: HTMLCanvasElement) => {
|
|||||||
width: BOX_WIDTH * zoom.value,
|
width: BOX_WIDTH * zoom.value,
|
||||||
height: BOX_HEIGHT * zoom.value,
|
height: BOX_HEIGHT * zoom.value,
|
||||||
PDFPage: {
|
PDFPage: {
|
||||||
index: page.value - 1,
|
index: multiPage.value ? getCanvasId(canvas) - 1 : page.value - 1,
|
||||||
width: PDFPageWidth,
|
width: PDFPageWidth,
|
||||||
height: PDFPageHeight,
|
height: PDFPageHeight,
|
||||||
},
|
},
|
||||||
@ -679,8 +772,8 @@ const addZoneEvent = async (e: PointerEvent, canvas: HTMLCanvasElement) => {
|
|||||||
signature.zones.push(newZone);
|
signature.zones.push(newZone);
|
||||||
userSignatureZone.value = newZone;
|
userSignatureZone.value = newZone;
|
||||||
|
|
||||||
await setPage(page.value);
|
await resetPages();
|
||||||
setTimeout(() => drawAllZones(page.value), 200);
|
setTimeout(drawAllZones, 200);
|
||||||
canvasEvent.value = "select";
|
canvasEvent.value = "select";
|
||||||
adding.value = true;
|
adding.value = true;
|
||||||
};
|
};
|
||||||
@ -695,14 +788,15 @@ init();
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
#canvas {
|
canvas {
|
||||||
box-shadow: 0 20px 20px rgba(0, 0, 0, 0.2);
|
box-shadow: 0 20px 20px rgba(0, 0, 0, 0.2);
|
||||||
|
margin: 1rem auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.onAddZone {
|
.onAddZone {
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
|
|
||||||
#canvas {
|
canvas {
|
||||||
cursor: copy;
|
cursor: copy;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -716,6 +810,10 @@ div#action-buttons {
|
|||||||
div.pdf-tools {
|
div.pdf-tools {
|
||||||
background-color: #f3f3f3;
|
background-color: #f3f3f3;
|
||||||
font-size: 0.6rem;
|
font-size: 0.6rem;
|
||||||
|
label {
|
||||||
|
font-size: 0.75rem !important;
|
||||||
|
margin: auto 0 auto 0.3rem;
|
||||||
|
}
|
||||||
button {
|
button {
|
||||||
font-size: 0.75rem !important;
|
font-size: 0.75rem !important;
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,8 @@ const appMessages = {
|
|||||||
loading: 'Chargement...',
|
loading: 'Chargement...',
|
||||||
remove_sign_zone: 'Enlever la zone',
|
remove_sign_zone: 'Enlever la zone',
|
||||||
return: 'Retour',
|
return: 'Retour',
|
||||||
|
see_all_pages: 'Voir toutes les pages',
|
||||||
|
all_pages: 'Toutes les pages',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user